繁体   English   中英

使用or运算符在两个字符串之间进行正则表达式匹配

[英]Regex Match Between Two Strings With Or Operator

我试图寻找解决方案来解决这个问题,但只发现了在两个字符串之间进行搜索的一般问题。

本质上,我正在尝试查找任何未用于在SQL脚本中创建表的SELECT语句。

我目前在Sublime Text 3中使用此正则表达式: ;(\\h|\\v|/\\*(?s).+?\\*/)+((SELECT|SEL)(?s).+?;)

关键是要找到在“;”之后出现的SELECT语句。 可以有垂直空格,水平空格或两者之间的注释块。

当要在注释块之间插入内容时,这将无法正常工作。 例如

;
/*Comment Block*/
CREATE TABLE table AS SELECT * FROM other_table1 AS a INNER JOIN (
/*Comment Block*/
SELECT *
FROM other_table2
) AS b
ON a.key = b.key
;

之所以会匹配,是因为从技术上讲CREATE TABLE在/ *和* /之间。 我尝试将匹配设置为非贪婪,如果仅使用正则表达式/\\*(?s).+?\\*/则可以/\\*(?s).+?\\*/ 一次只能选择一个注释块,但是与OR运算符“ |”一起使用时 (很抱歉,如果从技术上来说,这不是一个“或”运算符),这似乎很贪心。

关于如何解决此问题的任何想法?

(s).+?/\\*延迟匹配所有字符,包括换行符,直到找到/* 一旦正则表达式引擎找到第一个注释块的末尾,它将继续与SELECT匹配,但不能匹配。 由于这是一个惰性搜索,因此如果找到SELECT ,它将放弃任何进一步的搜索,但是它没有回溯并继续 然后,找到第二个注释块的末尾,之后便可以找到SELECT

对正则表达式展览品的根本误解是在需要非回溯匹配的情况下使用了惰性匹配。 懒惰并不意味着不会发生回溯。 惰性意味着不会发生不必要的回溯。

避免回溯的方法是使用原子组,例如(?>example atomic group) 您的正则表达式将变为:

;(?>\\h|\\v|/\\*(?s).+?\\*/)+((SELECT|SEL)(?s).+?;)

看到这个动作

避免此问题的另一种方法是避免搜索注释块中的所有字符。 实现此目的的方法(显然)是在注释块中匹配所有不以*开头,后跟/字符。 转换为([^*]|\\*(?=/))+ 您的正则表达式将变为:

;(\\h|\\v|/\\*([^*]|\\*(?=/))+\\*/)+((SELECT|SEL)(?s).+?;)

看到这个动作

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM