如何执行负向回顾后断言?

3
我将尝试执行正则表达式负向预查,以找到SQL中关键字的存在,但这些关键字不是注释的一部分。
例如:
-- some comments create
/* some more comments create
some more create
*/ 
create

只有最后一个“create”关键词需要匹配,因为其他所有关键词都在注释中

到目前为止,我有以下内容

(?<!--.*?)(?<!/\*.*?)\bcreate\b

通过这种方式,可以消除前两个“create”单词。

我需要能够跨越多行消除第三个单词,但是我需要使用异常处理机制来匹配第四个单词的结束注释标记(*/)

我查看了许多正则表达式网站,如http://www.rexegg.com/regex-lookarounds.html,但我无法弄清楚如何做到这一点。


1
在添加信息时,请编辑您的帖子。 - Thomas Ayoub
不确定 C# 是否实现了可变长度的负回顾后发断言。 - Toto
@Toto:是的,.NET正则表达式支持无限宽度的后顾断言。Dave,你可以匹配并捕获注释,然后只需匹配“create”以执行任何更改。请参见(--.*|/\*[^*]*\*+([^/*][^*]*\*+)*/)|\bcreate\b - Wiktor Stribiżew
Wiktor的评论解决了我的问题。感谢所有其他做出贡献的人。 - davros
2个回答

0
(?<!--.*)(?<!/\*(?s:(?!\*/).)*)\bcreate\b

第二次回溯的目标是确保在找到/*之前它不会跨越任何*/实例。我正在使用的技术称为温和的前瞻
(?s:(?!\*/).)*

每次匹配一个字符时,它首先进行负向前瞻以确保它不是您要排除的序列的第一个字符。
(?s: 中的 s 使该组中的所有内容在 Singleline 模式下匹配,这意味着 . 匹配换行符。

-1

我认为删除注释更容易,方法如下:

    // use these regex patterns

     public string RemoveSQLComments(string sqlQuery)
        {
            Regex r1 = new Regex(@"(\/\*)(?s:(?!\*\/).)*(\*\/)", System.Text.RegularExpressions.RegexOptions.Multiline &
                                  System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            Regex r2 = new Regex("(--)[^\r\n$]*(?=(\r|\n|$))", System.Text.RegularExpressions.RegexOptions.Multiline &
                                  System.Text.RegularExpressions.RegexOptions.IgnoreCase);

            return r2.Replace(r1.Replace(sqlQuery, ""), "");
        }

结果将是没有任何注释的SQL字符串。


这里有几个问题,包括:(1) () 在字符类中没有特殊含义,(2) 你使用 | 来组合选项,而不是 &;你之所以能够得逞,是因为这两个选项对你的正则表达式没有任何影响。此外,没有必要在答案中添加完整的命名空间;可以假设任何提问 C# 问题的人都知道如何使用 using - Alan Moore
你的第一个正则表达式无法匹配包含任何字符 (*/) 的注释,例如 /* (perfectly * valid / comment) */。你所尝试的需要使用负向先行断言,就像我在我的答案中演示的那样:(?s:(?!\*/).)*。而使用 & 来组合选项可以确保没有选项被应用。你的正则表达式之所以匹配成功是因为你不需要任何选项。 - Alan Moore

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