使用标记标签的化学式中的 sed/awk 下标数字

使用标记标签的化学式中的 sed/awk 下标数字

我有数百个文本文件,其中包括化学式以及包括数值的叙述。公式前面始终有空格,但后面可以有空格、逗号、句点等。

问题是:公式未格式化为将数字显示为下标,例如:

H2SO4、C5H11OH。

我想将下标格式化为 HTML 标签,例如:

H<sub>2</sub>SO<sub>4</sub>, C<sub>5</sub>H<sub>11</sub>OH

这样下标就会以 HTML 形式呈现,例如:

H 2 SO 4 , C 5 H 11 OH

我曾经尝试过用 Java、php 等来实现这一点,但实现必然是混乱和尴尬的。我怀疑有一种优雅的 sed/awk 方法。

显然,解决方案的一部分是制作一个正则表达式,匹配一个字母后跟一个或多个数字,作为公式检测机制(可能会出现误报,我稍后会手动纠正)。然后,给定如此确定的公式,sed 替换需要在每个数字或数字序列之前添加标签sub,并在其后添加子标签闭合。

肯定有一句台词可以做到这一点,但我无法理解。

有任何想法吗?

答案1

例如:

sed -r 's:([A-Za-z])([0-9]+):\1<sub>\2</sub>:g'  

应该做这项工作。

(匹配一个字母后跟一组数字,并将其记住为 \1 和 \2。将所有这些替换为相同的字母 (\1) 加上标记中包含的数字组 (\2) sub。)

答案2

由于您提到可能存在误报,需要稍后手动更正,因此您可能需要考虑一种稍微更稳健的形式,其中包含以下限制:

  1. 所有化学符号开始带有一个大写字母。
  2. 所有化学符号要么是一个大写字母,要么是一个大写字母后跟一个小写字母,除了临时指示符我会忽略这一点。

鉴于这些你可以尝试,例如:

sed 's|\([[:upper:]][[:lower:]]\{0,1\}\)\([0-9]\{1,\}\)|\1<sub>\2</sub>|g'

使用非 POSIX-r选项,可读性会稍好一些,但可移植性较差:

sed -r 's|([[:upper:]][[:lower:]]?)([0-9]+)|\1<sub>\2</sub>|g'

通过确保全部的正在处理的“单词”不包含连续的小​​写字母,当然可以通过专门检查每个可能的化学符号来进一步改进,但这会变得越来越花哨,但回报却越来越少。上述内容应该已经大大减少了误报。

答案3

分组和反向引用就是诀窍。感谢您朝着正确的方向推动。最后,我使用了以下内容:

sed 's/\([A-Z][a-z]*\)\([0-9][0-9]*\)/\1<sub>\2<\/sub>/g' file

这可以容忍文档中出现标题(例如 h2)的情况。

相关内容