grep输出与Python3中的"re.findall()"输出不同
这是我的输入文件
input.txt
www.ncbi.nlm.nih.gov/entrez/viewer.fcgi?db=nucleotide&val=NM_003157.1 rs 1123
www.ncbi.nlm.nih.gov/entrez/viewer.fcgi?db=nucleotide&val=NM_006157 dd 12
www.ncbi.nlm.nih.gov/entrez/viewer.fcgi?db=nucleotide&val=NM_021018.2 ff 121
www.ncbi.nlm.nih.gov/entrez/viewer.fcgi?db=nucleotide&val=NM_000908.2 rs10472828-?
期望的输出
NM_003157.1
NM_006157
NP_021018.2
NM_000908.2
我的正则表达式
egrep "N[A-Z]_[0-9]{1,}(\.[1-9])*" input.txt
我的代码
f=open("input.txt")
for i in f:
print(re.findall("N[A-Z]_[0-9]{1,}(\.[1-9])*",i.strip()))`
python的输出:
[]
[]
['.3']
[]
我用grep命令得到的输出和我期望的输出完全一致。但是当我把同样的正则表达式放到我的python3代码里时,输出却不对。
2 个回答
1
通过使用grep命令的 oP
参数,
$ grep -oP '(?<=;val=)\S*(?=\s)' file
NM_003157.1
NM_006157
NM_021018.2
NM_000908.2
这里用到了一个叫做“回顾”的技巧,它可以在字符串 ;val=
后面查找,并匹配所有后面跟着空格的非空字符。
通过使用egrep,
$ egrep -o "N[A-Z]_[0-9]{1,}(\.[1-9])*" file
NM_003157.1
NM_006157
NM_021018.2
NM_000908.2
在 egrep
中,你缺少了 -o
参数,这个参数的作用是告诉 egrep
只打印出匹配到的字符串。
3
你在Python的模式中多了一个.
,而egrep
版本没有这个;把它去掉。
接下来,re.findall()
会返回捕获组,而不是整个匹配结果,如果有这样的组的话。你可以用(?:...)
代替(...)
来让这个组不被捕获:
re.findall(r'N[A-Z]_[0-9]+(?:\.[1-9])*', i.strip())
现在,re.findall()
会生成一个列表,每行一个匹配结果:
>>> import re
>>> text = '''\
... www.ncbi.nlm.nih.gov/entrez/viewer.fcgi?db=nucleotide&val=NM_003157.1 rs 1123
... www.ncbi.nlm.nih.gov/entrez/viewer.fcgi?db=nucleotide&val=NM_006157 dd 12
... www.ncbi.nlm.nih.gov/entrez/viewer.fcgi?db=nucleotide&val=NM_021018.2 ff 121
... www.ncbi.nlm.nih.gov/entrez/viewer.fcgi?db=nucleotide&val=NM_000908.2 rs10472828-?
... '''
>>> f = text.splitlines()
>>> for i in f:
... print(re.findall(r"N[A-Z]_[0-9]+(?:\.[1-9])*", i.strip()))
...
['NM_003157.1']
['NM_006157']
['NM_021018.2']
['NM_000908.2']
如果你只想要每行一个匹配结果,使用re.search()
会更好,然后在结果上调用MatchObject.group()
:
>>> for i in f:
... print(re.search(r"N[A-Z]_[0-9]+(?:\.[1-9])*", i.strip()).group())
...
NM_003157.1
NM_006157
NM_021018.2
NM_000908.2