我有一个包含行的文件,例如:
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)
任何想法如何改善我的正则表达式?我尝试使用*和+符号,但我不确定如何最终创建它。 我正在寻找类似的帖子,但无法找到它:(
答案 0 :(得分:6)
您可以将re.findall
与r'\$[^$]+\$'
正则表达式
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>
模式详情:
\$
- 美元符号(字面值)[^$]+
- 除$
\$
- 一个字面的美元符号。 注意:[^$]
是否定字符类,它匹配任何字符,但是在类中定义的字符。使用否定字符类可加速匹配,因为.*?
延迟点模式在两个$
之间的字符串中的每个位置处扩展,因此需要更多步骤来完成并返回匹配。
这种模式的变体只能获得$...$
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)