正则表达式在嵌套括号的匹配项内替换字符,或仅在匹配项之外的文本内替换 [英] Regex replace character within match of nested parenthesis, or replace only within text outside of match
问题描述
我正在编写一个AutoHotkey脚本,该脚本将根据屏幕上选择的文本来格式化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
我首先用逗号+回车符+ tab 替换逗号,但是当我遇到包含括号内使用逗号的函数的SQL语句时,会产生不良结果.我的第一个解决方案是使用此AutoHotkey RegEx命令排除括号内的逗号:
; Find commas not in parenthesis and suffix with <CR><Tab>
s := RegExReplace( s, ",(?![^()]*\))", ",`r`n" . Tab )
问题在于,有时括号是嵌套的,而简单的RegEx无效.
经过一番挖掘,我找到了一个递归的正则表达式,它将选择每个组的最外面的括号.
\((?:[^()]++|(?R))*\)
现在的挑战是,
- 如何选择该组之外的所有内容,并在其中找到/替换 或
- 如何仅对该组中的文本应用搜索/替换?
我发现可以在表达式中使用或来查找括号中的任何内容 OR 任何逗号.使用此方法,它将不会选择括号组内的任何单个逗号. (感谢此帖子中的 zx81 .)
,|\((?:[^()]++|(?R))*\)
使用该表达式,我可以使用替换|$0|
用|
字符包围每个匹配的组.然后,很容易用|,|
查找独立逗号并替换为我的回车模式,然后用空字符串替换所有剩余的|
.
; AutoHotkey snippet below
s := RegExReplace( s, ",|\((?:[^()]++|(?R))*\)", "|$0|" )
s := StrReplace( s, "|,|" , ",`r`n" . A_Tab )
s := StrReplace( s, "|" , "")
I'm writing an AutoHotkey script that will format SQL statements from text selected on the screen. I want to turn a statement like this:
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
into this:
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
I started by replacing commas with comma+carriage return+tab but when I encountered SQL statements containing functions using commas within parenthesis it produced undesirable results. My first solution was to exclude commas within parenthesis, with this AutoHotkey RegEx command:
; Find commas not in parenthesis and suffix with <CR><Tab>
s := RegExReplace( s, ",(?![^()]*\))", ",`r`n" . Tab )
The problem is that sometimes parenthesis are nested, and that simple RegEx didn't work.
After some digging I found a recursive RegEx that would select the outer most parenthesis of each group.
\((?:[^()]++|(?R))*\)
Now the challenge is,
- how do I select everything outside of that group and find/replace within it, or
- how do I apply a search/replace to only text within that group?
SO encourages us to answer our own question. In the process of writing this up I found a solution and I will post it below. Feel free to share solutions of your own. I would like to further my understanding of regular expressions.
I discovered that I can use an or in my expression to find anything in parenthesis OR any comma. With this method it won't select any individual commas that are inside the parenthesis groups. (Thanks to zx81 in this post.)
,|\((?:[^()]++|(?R))*\)
With that expression I can use the substitution |$0|
to surround each matching group with the |
character. Then it is easy to find the stand-alone commas with |,|
and replace with my carriage return pattern, then replace all remaining |
's with an empty string.
; AutoHotkey snippet below
s := RegExReplace( s, ",|\((?:[^()]++|(?R))*\)", "|$0|" )
s := StrReplace( s, "|,|" , ",`r`n" . A_Tab )
s := StrReplace( s, "|" , "")
这篇关于正则表达式在嵌套括号的匹配项内替换字符,或仅在匹配项之外的文本内替换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!