正则表达式在嵌套括号的匹配项内替换字符,或仅在匹配项之外的文本内替换 [英] Regex replace character within match of nested parenthesis, or replace only within text outside of match

查看:173
本文介绍了正则表达式在嵌套括号的匹配项内替换字符,或仅在匹配项之外的文本内替换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个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))*\)
 

现在的挑战是,

  1. 如何选择该组之外的所有内容,并在其中找到/替换
  2. 如何仅对该组中的文本应用搜索/替换?

Regex演示

SO鼓励我们回答自己的问题.在撰写本文的过程中,我找到了一个解决方案,并将其发布在下面.随时分享您自己的解决方案.我想进一步了解正则表达式.

解决方案

我发现可以在表达式中使用来查找括号中的任何内容 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,

  1. how do I select everything outside of that group and find/replace within it, or
  2. how do I apply a search/replace to only text within that group?

Regex Demo

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, "|" , "")

Regex substitution example

这篇关于正则表达式在嵌套括号的匹配项内替换字符,或仅在匹配项之外的文本内替换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆