我对regexp很新,而且我错过了捕捉群体的一些东西。
假设我有一个类似
的文件路径test.orange.john.edn
我想捕捉两组:
test.orange.john (which is the body)
edn (which is the extension)
我使用了它(以及它的变体,将$取出等等)
^([a-z]*.)*.([a-z]*$)
但它仅捕获xm
我错过了什么?我不明白为什么我没被捕获,身体也是...... 我在网上找到答案来捕获扩展,但我不明白那里的问题。
由于
答案 0 :(得分:2)
^([a-z]*.)*.([a-z]*$)
正则表达式的效率非常低,因为这里有许多不必要的回溯步骤。
匹配字符串的开头,然后[a-z]*.
匹配0次以上。这意味着,引擎尽可能多地[a-z]
匹配(即它匹配test
直到第一个点),然后.
匹配点(但只是因为.
匹配任何角色!)。因此,此([a-z]*.)*
仅匹配test.orange.john.edn
捕获edn
,因为重复捕获组仅保留最后捕获的值。
您已在第1组at this step中拥有edn
。现在,.([a-z]*$)
应该为.
(任何字符)模式分配子字符串。回溯返回并找到n
- 现在,Group 1 only contains ed
。
对于你的任务,你应该逃避最后的.
以匹配文字点,也许,最好的表达是
^(.*)\.(.*)$
请参阅demo
它会将所有字符串与第一个(.*)
匹配到最后,然后将回溯以查找最后一个.
符号(因此,第1组将包含从开头到结尾的所有文本最后.
),然后将其余字符串捕获到第2组。
如果不必存在点(即文件名没有扩展名),请添加一个可选组:
^(.*)(?:\.(.*))?$
请参阅another demo
答案 1 :(得分:0)
您可以尝试:
In [1025]: def f(d):
for k, v in d.items():
yield (k, d[k].keys()[0], d[k].values()[0])
......:
In [1026]: for i in f(d):
print i
......:
('a', 'x', 45)
('b', 'r', 34)