【问题标题】:grep output not same as "re.findall()" output in python3 [closed]grep输出与python3中的“re.findall()”输出不同[关闭]
【发布时间】:2014-07-07 13:46:10
【问题描述】:

这是我的输入文件

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 代码中使用相同的正则表达式时,我得到了不正确的输出。

【问题讨论】:

  • 1.你的正则表达式不一样,2.什么是错误的输出?
  • 您应该使用parse_qs(和urlsplit 朋友)来解析查询字符串,而不是正则表达式。

标签: python regex unix grep


【解决方案1】:

您的 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

【讨论】:

  • 如果后面的字符不能作为转义字符,反斜杠将被“自动转义”,因此"\." 隐式变为"\\.",所以这不是问题。不过,额外的. 是。
  • @TimPietzcker:确实,我后来意识到了这一点。捕获组是这里最大的问题。
  • @diablo8226:“它不工作”不是一个有用的问题描述。
  • @diablo8226:它非常有效;我包含了一些演示输出。
  • 我弄错了。thnx
【解决方案2】:

通过带有oP参数的grep,

$ grep -oP '(?<=;val=)\S*(?=\s)' file
NM_003157.1
NM_006157
NM_021018.2
NM_000908.2

lookbehind 用于查找字符串;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 只打印匹配的字符串。

【讨论】:

  • 我想知道在 findall 中 wat 是错误的。 grep 只是用来显示输出
  • 我不知道为什么一个简单的 grep 就可以完成一个很长的 python 代码。
  • python 代码只是另一个代码的一个小模块。
  • @diablo8226 更新了我对 egrep 的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-17
  • 1970-01-01
  • 1970-01-01
  • 2015-02-25
  • 1970-01-01
相关资源
最近更新 更多