【发布时间】:2016-01-29 13:59:11
【问题描述】:
在处理 this answer 的过程中,我偶然发现了 Python 的重复正则表达式异常。
假设我得到了一个 CSV 字符串,其中包含任意数量的带引号和不带引号的元素:
21, 2, '23.5R25 ETADT', '描述,带逗号'
我想用'\t' 替换所有','s 外部引号。所以我想要一个输出:
21\t2\t'23.5R25 ETADT'\t'描述,带逗号'
由于字符串中自然会有多个匹配项,因此我将使用g 正则表达式修饰符。我将使用的正则表达式将匹配引号之外的字符或带引号的字符串,后跟 ',':
('[^']*'|[^',]*),\s*
我将替换为:
\1\t
现在的问题是正则表达式是 searching 而不是 matching 所以它可以选择跳过字符直到它可以匹配。所以我得到的不是我想要的输出:
21\t2\t'23.5R25 ETADT'\t'描述\t带逗号'
您可以在此处查看此行为的实时示例:https://regex101.com/r/sG9hT3/2
问。有没有办法锚定 g 修改后的正则表达式以在上一次匹配后的字符处开始匹配?
对于那些熟悉 Perl 强大的正则表达式的人,Perl 提供了\G。这允许我们检索匹配的最后一个位置的结尾。因此,在 Perl 中,我可以使用正则表达式完成我所要求的:
\G('[^']*'|[^',]*),\s*
这将强制在最终引用的元素中出现不匹配。因为与其允许正则表达式实现找到正则表达式匹配的点,\G 会强制它在 first 字符处开始匹配:
'描述,用逗号'
【问题讨论】:
-
看看
,?\s*('[^']*'|[^',]*)。或者更类似于演示的,?[ ]*('[^'\n]*'|[^',\n]*)。 -
@stribizhev 是的,这两种方法都是可行的。如果这就是所有可以做的,我很好。但我想回答的是我们是否可以锚定此搜索或强制它匹配,而不仅仅是搜索。
-
好吧,我想我明白了你的意思,如果你有任何疑问,请在我的回答下方留言。
标签: python regex search match repeat