我正在尝试编辑一个具有这种格式的多行的文件。
ATOM,9,HG,LEU,1,162.4,131.44,219.19,0,0,PROA
ATOM,10,CD1,LEU,1,163.3,130.88,219.73,0,0,PROA
ATOM,11,HD11LEU,1,163.54,130.77,219.97,0,0,PROA,
ATOM,12,HD12LEU,1,163.48,130.98,219.76,0,0,PROA,
对于第二次和第三次出现逗号之间的每个字符串
(e.g. HG, CD1, HD11LEU etc.)
,我想在最后一次出现数字之后添加一个逗号,前提是字符串中有一个数字并且数字后跟一个字符(e.g. HD12LEU)
。基本上 HD12LEU
应转换为 HD12,LEU
。
这就是文件应有的样子。
ATOM,9,HG,LEU,1,162.4,131.44,219.19,0,0,PROA
ATOM,10,CD1,LEU,1,163.3,130.88,219.73,0,0,PROA
ATOM,11,HD11,LEU,1,163.54,130.77,219.97,0,0,PROA,
ATOM,12,HD12,LEU,1,163.48,130.98,219.76,0,0,PROA,
我希望同时对文件中的所有行执行此操作。请建议一种在 R/Python/Linux 中执行此操作的方法。
这是 Python 中的一种可能的解决方案(regex101 demo):
import re
text = """\
ATOM,9,HG,LEU,1,162.4,131.44,219.19,0,0,PROA
ATOM,10,CD1,LEU,1,163.3,130.88,219.73,0,0,PROA
ATOM,11,HD11LEU,1,163.54,130.77,219.97,0,0,PROA,
ATOM,12,HD12LEU,1,163.48,130.98,219.76,0,0,PROA,"""
text = re.sub(
r"^([^,]+,[^,]+,)([A-Z]+\d+)([A-Z]+)", r"\g<1>\g<2>,\g<3>", text, flags=re.M
)
print(text)
打印:
ATOM,9,HG,LEU,1,162.4,131.44,219.19,0,0,PROA
ATOM,10,CD1,LEU,1,163.3,130.88,219.73,0,0,PROA
ATOM,11,HD11,LEU,1,163.54,130.77,219.97,0,0,PROA,
ATOM,12,HD12,LEU,1,163.48,130.98,219.76,0,0,PROA,
perl=TRUE
的R 和带有 PyPI 正则表达式模块的 Python 或使用 PCRE 或 Onigmo 正则表达式引擎的任何其他语言都支持
\K
,它将字符串中的正则表达式指针重置为当前位置,并丢弃所有先前匹配的字符那些通过比赛返回的。如果使用其中之一,则可以用逗号替换以下正则表达式的(零宽度)匹配:
^(?:[^,]*,){2}[^\d,]*\d+\K(?=[^\d,])
其中设置了标志
g
(“全局”,第一次匹配后不返回)和 m
(“多行”,^
和 $
分别匹配行的开头和结尾)。
正则表达式可以分解如下。
^ # match the beginning of a line
(?: # begin a non-capture group
[^,]* # match zero or more chars other than a comma
, # match a comma
) # end non-capture group
{2} # execute above non-capture group twice
[^\d,]* # match zero or more chars other than a digit or comma
\d+ # match one or more digits
\K # reset pointer location and discard all previously-consumed chars
(?= # begin a positive lookahead
[^\d,] # march a character other than a digit or comma
) # end the positive lookahead
还可以将光标悬停在链接处表达式的每个部分上以获得其功能的解释。