在python中正则表达式中重复

时间:2016-08-22 20:50:31

标签: python regex python-2.7

我有一个包含行的文件,例如:

aaa$bb$ccc$ddd$eee
fff$ggg$hh$iii$jj

我需要接受$$里面的内容,所以期望的结果是:

 $bb$
 $ddd$
 $ggg$
 $iii$

我的结果:

$bb$
$ggg$

我的解决方案:

m = re.search(r'$(.*?)$', line)
    if m is not None:
        print m.group(0)

任何想法如何改善我的正则表达式?我尝试使用*和+符号,但我不确定如何最终创建它。 我正在寻找类似的帖子,但无法找到它:(

3 个答案:

答案 0 :(得分:6)

您可以将re.findallr'\$[^$]+\$'正则表达式

一起使用
import re
line = """aaa$bb$ccc$ddd$eee
fff$ggg$hh$iii$jj"""
m = re.findall(r'\$[^$]+\$', line)
print(m)
# => ['$bb$', '$ddd$', '$ggg$', '$iii$']

请参阅Python demo

请注意,您需要转义$并删除re.findall的捕获组,以返回$...$子字符串,而不仅仅是$内的字符串。< / p>

模式详情

  • \$ - 美元符号(字面值)
  • [^$]+ - 除$
  • 以外的1个或多个符号
  • \$ - 一个字面的美元符号。

注意[^$]否定字符类,它匹配任何字符,但是在类中定义的字符。使用否定字符类可加速匹配,因为.*?延迟点模式在两个$之间的字符串中的每个位置处扩展,因此需要更多步骤来完成并返回匹配。

这种模式的变体只能获得$...$ s中的文本:

re.findall(r'\$([^$]+)\$', line) 
               ^     ^

another Python demo。请注意添加了(...)捕获组,以便re.findall只能返回捕获的,而不是匹配的

答案 1 :(得分:3)

re.search只找到第一场比赛。也许你想要re.findall,它返回字符串列表,或者re.finditer返回匹配对象的迭代器。此外,您必须将$转移到\$,因为未转义的$表示&#34;行尾#34;。

示例:

>>> re.findall(r'\$.*?\$', 'aaa$bb$ccc$ddd$eee')
['$bb$', '$ddd$']
>>> re.findall(r'\$(.*?)\$', 'aaa$bb$ccc$ddd$eee')
['bb', 'ddd']

另一项改进是使用[^$]*代替.*?;前者表示除$以外的任何字符为零或更多;这可以避免更多的病态回溯行为。

答案 2 :(得分:1)

你的正则表达式很好。 re.search只找到一行中的第一个匹配项。您正在寻找re.findall,它会找到所有非重叠的匹配项。最后一点对你很重要,因为你有相同的开始和结束分隔符。

for m in m = re.findall(r'$(.*?)$', line):
    if m is not None:
        print m.group(0)