求助:如何用sed为分子式中无计数的元素后插入1?
问题分析
你的需求是给分子式中未标注计数的元素自动补全1,但现有sed命令只覆盖了两个大写元素相邻和元素在空格前的场景,漏掉了关键情况——比如CH4里的C后面跟着带数字的H4,你的正则没匹配到这种无数字的元素开头;还有像NH3O末尾的O,如果你的命令只处理空格前的元素,那行尾的元素也会被遗漏吗?不对,你的第二个规则是处理空格前的元素,但如果分子式是行尾的话就没覆盖到,这也是问题之一。
解决方案
用GNU sed的扩展正则(-E选项),可以精准匹配所有需要补1的元素场景:
sed -E 's/([A-Z])([^0-9])/\11\2/g; s/([A-Z])$/\11/g' input.txt
命令拆解解释
第一个替换规则
s/([A-Z])([^0-9])/\11\2/g:([A-Z]):捕获单个大写元素符号(比如C、N、O)([^0-9]):匹配元素后面非数字的字符(包括另一个大写元素、空格、换行等)- 替换为
\11\2:在捕获的元素后插入1,同时保留后面的非数字字符 - 这个规则能处理绝大多数场景:比如
CH→C1H、O→O1、NO→N1O
第二个替换规则
s/([A-Z])$/\11/g:- 专门匹配行尾的大写元素(比如单独的
O作为分子式),给它补1,避免遗漏这种极端情况
- 专门匹配行尾的大写元素(比如单独的
测试验证
把你的输入字符串:
NH3O CH4 CHN C2NOPH3
用上述命令处理后,输出完全符合你的预期:
NH3O1 C1H4 C1H1N1 C2N1O1P1H3
扩展:支持双字符元素(如Fe、Cu)
如果你的分子式里包含双字符元素(首字母大写,第二个小写),可以把正则调整为匹配[A-Z][a-z]?,命令修改为:
sed -E 's/([A-Z][a-z]?)([^0-9])/\11\2/g; s/([A-Z][a-z]?)$/\11/g' input.txt
这样FeO会被处理为Fe1O1,满足更复杂的分子式需求。
内容的提问来源于stack exchange,提问作者MirrG
相关产品推荐
相关产品推荐

