【问题标题】:How to perform a negative lookbehind?如何进行负面的回顾?
【发布时间】:2016-05-19 11:43:28
【问题描述】:

我正在尝试在后面执行正则表达式否定查找,以发现 SQL 中存在不属于评论的关键字

例如

-- some comments create
/* some more comments create
some more create
*/ 
create

只有最后一个 create 关键字应该匹配,因为所有其他关键字都在 cmets 中

到目前为止我有这个

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

这消除了前两个“创建”词。

我需要能够通过跨越多行来消除第三个,但是我需要通过在结束注释 (*/) 标记上使用异常来匹配第四个

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

【问题讨论】:

  • 添加信息时请edit你的帖子
  • 不确定C# 是否实现了可变长度负向后查找。
  • @Toto:是的,.NET 正则表达式支持无限宽度的后视。 Dave,您可以匹配并捕获 cmets,然后匹配 create 以对其执行任何更改。见(--.*|/\*[^*]*\*+([^/*][^*]*\*+)*/)|\bcreate\b
  • Wiktor 的评论解决了我的问题。感谢所有其他做出贡献的人。

标签: c# regex


【解决方案1】:
(?<!--.*)(?<!/\*(?s:(?!\*/).)*)\bcreate\b

第二次后视的目标是确保它在找到/* 之前不会跨越*/ 的任何实例。我使用的技术称为tempered lookahead

(?s:(?!\*/).)*

每次匹配一个字符时,它首先会进行否定的前瞻,以确保它不是您要排除的序列的第一个字符。

(?s: 中的s 导致该组中的所有内容都以Singleline 模式匹配,这意味着. 匹配换行符。

【讨论】:

    【解决方案2】:

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

        // 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, ""), "");
            }
    

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

    【讨论】:

    • 这里有几个问题,包括:(1)()在字符类中没有特殊意义,(2)你使用|组合选项,而不是&amp;;你侥幸逃脱,因为这些选项都不会对你的正则表达式产生任何影响。此外,没有必要用完整的命名空间来混淆答案;可以假设任何提出 C# 问题的人都知道如何使用 using
    • 您的第一个正则表达式不会匹配包含任何字符 (*/) 的评论,例如 /* (perfectly * valid / comment) */。正如我在我的回答中所展示的那样,您正在尝试做的事情需要一个否定的前瞻:(?s:(?!\*/).)*。并且使用&amp; 组合选项可确保应用none 选项。您的正则表达式匹配,因为您不需要任何选项。
    猜你喜欢
    • 2013-08-03
    • 2014-12-20
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    相关资源
    最近更新 更多