我使用的是 Python 2.7,我非常熟悉正则表达式的使用以及如何在 Python 中使用它们。我想使用正则表达式将逗号分隔符替换为分号。问题是用双引号包裹的数据应该保留嵌入的逗号。这是一个例子:
之前:
"3,14","1,000,000",hippo,"cat,dog,frog",plain text,"2,25"
之后:
"3,14";"1,000,000";hippo;"cat,dog,frog";plain text;"2,25"
是否有一个正则表达式可以做到这一点?
请您参考如下方法:
这是另一种避免测试所有字符串的方法,直到每次出现都进行前瞻。它是一种(或多或少)\G re 模块的功能模拟。 此模式不是测试逗号之后的内容,而是查找逗号之前的项目(显然是逗号),并且以一种使每个整体匹配都与先例连续的方式编写。
re.sub(r'(?:(?<=,)|^)(?=("(?:"")*(?:[^"]+(?:"")*)*"|[^",]*))\1,', r'\1;', s)
详情:
(?: # ensures that results are contiguous
(?<=,) # preceded by a comma (so, the one of the last result)
| # OR
^ # at the start of the string
)
(?= # (?=(a+))\1 is a way to emulate an atomic group: (?>a+)
( # capture the precedent item in group 1
"(?:"")*(?:[^"]+(?:"")*)*" # an item between quotes
|
[^",]* # an item without quotes
)
) \1 # back-reference for the capture group 1
,
这种方式的优点是它减少了获得匹配的步骤数,并且无论之前的项目是什么,它都提供接近常数的步骤数(请参阅 regex101 调试器)。原因是所有字符都只匹配/测试一次。因此,即使模式更长,效率也更高(并且增益会增加,尤其是长线时)
这里的原子组技巧只是为了减少最后一项(后面没有逗号)失败之前的步骤数。
请注意,该模式处理内部带有转义引号(两个连续引号)的引号之间的项目:"abcd""efgh""ijkl","123""456""789",foo
