Python正则表达式中的“无需重复”

2024-03-29 05:32:49 发布

您现在位置:Python中文网/ 问答频道 /正文

下面是一个正则表达式-由egrep尝试,然后由Python 2.7尝试:

$ echo '/some/path/to/file/abcde.csv' | egrep '*([a-zA-Z]+).csv'

/some/path/to/file/abcde.csv

但是,Python中的相同正则表达式:

re.match(r'*([a-zA-Z]+)\.csv',f )

给出:

Traceback (most recent call last):
  File "/shared/OpenChai/bin/plothost.py", line 26, in <module>
    hosts = [re.match(r'*([a-zA-Z]+)\.csv',f ).group(1) for f in infiles]
  File "/usr/lib/python2.7/re.py", line 141, in match
    return _compile(pattern, flags).match(string)
  File "/usr/lib/python2.7/re.py", line 251, in _compile
    raise error, v # invalid expression
sre_constants.error: nothing to repeat

进行搜索时,发现此处似乎存在Python错误:

regex error - nothing to repeat

It seems to be a python bug (that works perfectly in vim). The source of the problem is the (\s*...)+ bit.

然而,我并不清楚:那么,上面显示的我的正则表达式的解决方法是什么——使python快乐

谢谢


Tags: csvtopathinpyrematchline
2条回答

您不需要模式中的*,它会导致问题,因为您试图量化模式的开头,但是没有任何东西需要量化,一个空字符串

当您

  • 任何量词(+?*{2}{4,5}等)放在模式的开头(例如re.compile(r'?')
  • 在字符串锚点的^/\A开始之后添加任何量词(例如re.compile(r'^*')
  • 在字符串锚点的$/\Z结尾之后添加任何量词(例如re.compile(r'$*')
  • 在单词边界后添加任何量词(例如re.compile(r'\b*\d{5}')

但是请注意,在Python re中,您可以量化任何查找,例如(?<!\d)*abc(?<=\d)?abc将产生相同的匹配,因为查找是可选的

使用

([a-zA-Z]+)\.csv

或匹配整个字符串:

.*([a-zA-Z]+)\.csv

demo

原因是*是不可替代的,因此被视为量词。它应用于正则表达式中前面的子模式。在这里,它用于模式的开头,因此不能量化任何内容。因此,不会抛出任何要重复的内容

如果它在VIM中“起作用”,那只是因为VIM正则表达式引擎忽略了这个子模式(与Java在字符类(如[([)]])中使用未scaped的[]时所做的相同)

python正则表达式引擎使用传统的NFA来匹配模式并不是一个bug。而字符*只有在前面加上标记时才起作用

'*'

Causes the resulting RE to match 0 or more repetitions of the preceding RE, as many repetitions as are possible. ab* will match ‘a’, ‘ab’, or ‘a’ followed by any number of ‘b’s.

因此,您可以使用.*来重复任何字符(.):

r'.*([a-zA-Z]+)\.csv'

python还提供了支持Unix shell样式通配符的模块^{}

>>> import fnmatch
>>> s="/some/path/to/file/abcde.csv"
>>> fnmatch.fnmatch(s, '*.csv')
True

相关问题 更多 >