regex替换嵌套括号匹配内的字符,或仅替换匹配外的文本

lbsnaicq  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(378)

这个问题在这里已经有答案了

从正则表达式中排除括号内的字符串(2个答案)
7个月前关门了。
我正在编写一个自动热键脚本,它将根据屏幕上选定的文本格式化sql语句。我想把一句话变成这样:

SELECT Name AS [Object Name], Switch([Type]=5,'Query',[Type]=-32768,'Form',[Type]=6,'Table') AS [Object Type], Switch([Type]=5,1,[Type]=-32768,2,[Type] In (1,4,6),6) AS [Object Type ID], Left(Name,4) as Prefix, LTrim(RTrim(Mid([Name],5,30))) as Suffix

对此:

SELECT Name AS [Object Name], 
    Switch([Type]=5,'Query',[Type]=-32768,'Form',[Type]=6,'Table') AS [Object Type], 
    Switch([Type]=5,1,[Type]=-32768,2,[Type] In (1,4,6),6) AS [Object Type ID], 
    Left(Name,4) as Prefix,
    LTrim(RTrim(Mid([Name],5,30))) as Suffix

我开始用逗号+回车+制表符替换逗号,但是当我遇到包含在括号中使用逗号的函数的sql语句时,它产生了不希望的结果。我的第一个解决方案是使用以下autohotkey regex命令排除括号中的逗号:

; Find commas not in parenthesis and suffix with <CR><Tab>
s := RegExReplace( s, ",(?![^()]*\))", ",`r`n" . Tab )

问题是有时括号是嵌套的,而简单的正则表达式不起作用。
经过一番挖掘,我发现了一个递归正则表达式,它可以选择每个组最外层的括号。

\((?:[^()]++|(?R))*\)

现在的挑战是,
如何选择该组之外的所有内容并在其中查找/替换,或者
如何仅对该组中的文本应用搜索/替换?
正则表达式演示
所以鼓励我们回答自己的问题。在写这篇文章的过程中,我找到了一个解决方案,我会把它贴在下面。请随意分享您自己的解决方案。我想进一步了解正则表达式。

bqf10yzr

bqf10yzr1#

我发现我可以在表达式中使用or来查找括号或逗号中的任何内容。使用此方法,它不会选择括号组中的任何单个逗号(感谢本文中的zx81。)

,|\((?:[^()]++|(?R))*\)

有了这个表达式,我就可以使用替换 |$0| 在每个匹配的组周围 | 性格。然后很容易找到独立的逗号 |,| 替换为我的回车模式,然后替换所有剩余的 | 是一个空字符串。

; AutoHotkey snippet below
s := RegExReplace( s, ",|\((?:[^()]++|(?R))*\)", "|$0|" )
s := StrReplace( s, "|,|" , ",`r`n" . A_Tab )
s := StrReplace( s, "|" , "")

正则表达式替换示例

相关问题