首页 > 解决方案 > 使用单个正则表达式删除固定模式中特定字符的多次出现

问题描述

首先,我知道如何使用两个正则表达式来解决这个问题,但我想知道这是否可以只使用一个来完成。请参阅此 Regex101.com 示例以获取以下说明。

这就是我想要做的:给了我一个 .csv 文件,其中一行如下所示:

AAA,AAA,AAA,AAA,一些文本和一个逗号这里和那里,测试,,,,,,,,,,,

AAA 可以是任意长度和任意数字/字符。这些是前四列。下一部分是

一些文本和一个逗号在这里和那里,测试

此字符串可以包含零个或多个逗号。让我们将其视为第五列,尽管从技术上讲它不是现在。其余的总是10 个逗号:

,,,,,,,,,,

目标是仅删除第五列内的逗号并将整行返回。所以从这里:

AAA,AAA,AAA,AAA,一些文本和一个逗号这里和那里,测试,,,,,,,,,,,

对此,请注意两个删除的逗号:

AAA,AAA,AAA,AAA,一些文本和一个逗号在这里和那里测试,,,,,,,,,,


这是我分两步完成的。
首先,我使用带有此正则表达式的第一个捕获组获得第五列:

(?:.*?,){4}(.*),{10}

然后我只使用:

,

匹配所有逗号并用空字符串替换它们。

我的猜测是你需要使用前瞻和后瞻,我尝试了很多变体,但我找不到任何解决方案。
有没有办法在一个正则表达式中实现这一点?感谢您的阅读。

标签: regexcsv

解决方案


以下正则表达式适用于 PCRE:

在此处查看它的使用情况

(?:^(?:[^,]+,){4}|\G(?!\A))[^,]+\K,(?!,{9}$)

这个怎么运作:

  • (?:^(?:[^,]+,){4}|\G(?!\A))匹配以下任一选项
    • ^(?:[^,]+,){4}从行首开始,匹配任意非逗号字符一次或多次,然后,;正好匹配这个系列 4 次
    • \G(?!\A))在上一场比赛结束时断言位置
  • [^,]+匹配除,一次或多次以外的任何字符
  • \K重置比赛的起点;任何先前使用的字符都不再包含在最终匹配中
  • ,从字面上匹配这个字符
  • (?!,{9}$)负前瞻确保后面的不是 9 个逗号和行尾(这是为了防止十个逗号中的第一个被替换)

在 Notepad++ 中完成此操作时,replace all 不适用于,一行中的每次迭代,但它仍然有效。只需继续单击全部替换,直到您看到消息全部替换:已替换 0 次


推荐阅读