正则表达式 - 是否可以仅使用正则表达式引擎实现递归替换?条件搜索替换

3

我正在编辑一些数据,我的最终目标是有条件地用点号.代替逗号,字符。我已经有了一个简陋的解决方案,所以这个问题是关于更好的实践方法建议和确定在增强型编程环境之外正则表达式引擎的可能性的讨论。

我已经尝试过很多,但六个小时的周六精神劳动已经足够了,我放弃了。 :)

我看过大约40篇关于正则表达式递归、替换等方面的stackoverflow文章,还有关于正则表达式和正则语言定义和历史的wiki.org和其他一些教程网站。其中大多数都集中在Python和PHP上。

下面是工作中使用的简陋的正则表达式(手动支持循环/搜索和替换):

(^.*)(?<=\()(.*?)(,)(.*)(?=\))(.*$)

一段输入的片段:

room_ass=01:macro_id=01: name=Left, pgm_audio=0, usb=0, list=(1*,3,5,7,),
room_ass=01:macro_id=02: name=Right, pgm_audio=1, usb=1, list=(2*,4,6,8,),
room_ass=01:macro_id=03: name=All, pgm_audio=1, list=(1,2*,3,4,5,6,7,8,),

并且期望的输出:

room_ass=01: macro_id=01: name=Left, pgm_audio=0, usb=0, list=(1*.3.5.7.),
room_ass=01: macro_id=02: name=Right, pgm_audio=1, usb=1, list=(2*.4.6.8.),
room_ass=01: macro_id=03: name=All, pgm_audio=1, list=(1.2*.3.4.5.6.7.8.),

就这样,只需将,替换为.,但仅在( )内进行。

这是一种我想看到的概念性(非工作)方法,在其中间组<3>会递归循环:

(^.*)(?<=\()([^,]*)([,|\d|\*]\3.*)(?=\))(.*$)
                   (          ^  )      

...其中每次递归迭代都会逐个字符或逗号地移动数据:

room_ass=01:macro_id=01: name=Left, pgm_audio=0, usb=0, list=(1*,3,5,7,),
                                                      iter 1-|  ^      |
                                                           2-|    ^    |
                                                           3-|      ^  |
                                                           4-|        ^|

或者 一个更简单的方法是告诉它在()之间掩盖/选择所有的,,但我在想这个问题时却失败了。 我经常使用文本编辑器来完成这样的小数据编辑任务,所以我想先确认一下SublimeText不能做到这一点,然后再深入研究Python。

欢迎提出所有建议和批评。请温柔点。<--#n00b 提前感谢! -B

2个回答

1
这只是一个猜测,因为我不使用SublimeText,假设SublimeText使用PCRE正则表达式。
请注意,您提到了“递归”,我认为您不是指Regular Expression Recursion,这与此处的问题不符。
类似这样的东西可能有效...您需要测试以确保它不会匹配文档中的其他内容,并查看SublimeText是否支持此功能...
这基于使用/K运算符来“保留”其前面的内容-您可以找到其他用途作为PCRE替代方案(解决方法)以使可变的前后环视不受PCRE支持。

正则表达式

\((?:(?:[^,\)]+),)*?(?:[^,\)]+)\K,

可视化

Regex Visualisation

正则表达式说明
  • 找到左括号字符 \(
  • 匹配下面的正则表达式 (?:(?:[^,\)]+),)*?
    • 0次到无限次,尽可能少地进行匹配(懒惰匹配)*?
    • 匹配下面的正则表达式 (?:[^,\)]+)
      • 匹配除了以下列表中的任意单个字符 [^,\)]+
        • 1次到无限次,尽可能多地进行匹配,回溯时进行缩减(贪婪匹配)+
        • 逗号字符 ,
        • 右括号字符 \)
    • 匹配逗号字符 ,
  • 匹配下面的正则表达式 (?:[^,\)]+)
    • 匹配除了以下列表中的任意单个字符 [^,\)]+
      • 1次到无限次,尽可能多地进行匹配,回溯时进行缩减(贪婪匹配)+
      • 逗号字符 ,
      • 右括号字符 \)
  • 将到目前为止匹配的文本保留,不会出现在整个正则表达式的匹配结果中 \K
  • 匹配逗号字符 ,

谢谢Dean!现在我终于明白了。您的正则表达式成功地发现了第一个逗号,而没有突出显示其他内容。 我本来希望能够使用递归让引擎继续扫描目标数据,并一次性选择括号中的所有逗号,并将每个逗号添加到捕获组中,就像在数组中跟踪字符一样。回溯现在似乎是更有可能实现这一点的工具,但仍然不太符合我的想象行为。 - befunkt

1

完美,而且非常简单。 谢谢,这正是我所需要的。 - befunkt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接