代码之家  ›  专栏  ›  技术社区  ›  Nicholas

什么regex允许我指定匹配文本必须在其中的开始和结束文本?

  •  1
  • Nicholas  · 技术社区  · 6 年前

        <!--- This is a test comment with from included, a match that we would like to avoid --->
    
        Test
    
        <cfquery>
            select  test
            from    table1,table2
        </cfquery>
    
        Test 2
    
        <cfquery>
            select  test
            from    table1
                inner join table2
        </cfquery>
    
        Test 3
    
        <cfquery>
            select  test
            from    table1,
                table2
        </cfquery>
    

        (<[cC][fF][qQ][uU][eE][rR][yY]>)[\S\s]*?([fF][rR][oO][mM])[\S\s]*?,[\S\s]*?(<\/[cC][fF][qQ][uU][eE][rR][yY]>)
    

    但是,这个Regex会匹配第一个块,然后匹配剩余的整个文件,因为尽管第二个块不匹配,但它不会停止尝试匹配,直到它到达文件底部的“/cfquery”。这是有道理的;它做的正是我要求它做的。但是我如何要求regex停止搜索某个单词呢?

    我尝试过使用锚点($和^和\z),但是这些锚点不是为我的需要而设计的,或者我没有正确地使用它们。我想告诉regex在匹配中不能出现斜杠可能是解决方法:

        (<[cC][fF][qQ][uU][eE][rR][yY]>)[\S\s]*?([fF][rR][oO][mM])[\S\s]*?,[\S\s]*?([^\/]*?)(<\/[cC][fF][qQ][uU][eE][rR][yY]>)
    

    但这和以前一样,我不知道为什么。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Tim Biegeleisen    6 年前

    老式隐式SQL连接的标志是 FROM 后跟一个表名,然后后跟可能的空格和逗号,这就是一个老式的连接。尝试在不区分大小写模式下搜索以下模式:

    FROM\s+\S+\s*,
    

    Demo

    这至少对您提供的示例数据有效。请注意,此模式不会突出显示整个有问题的查询。但是,也许出于您的目的,在有问题的查询中插入一行就足够了。

    如果您还希望只查找包含在 <cfquery> 标记,然后尝试以下模式:

    <cfquery>((?!<\/cfquery>).)*FROM\s+\S+\s*,.*?<\/cfquery>
    

    Demo

    . 匹配新行。如果您的工具不支持dot all,那么您可以使用 [\s\S] 在新线之间匹配。在这种情况下,上述正则表达式将变为:

    <cfquery>((?!<\/cfquery>)[\s\S])*FROM\s+\S+\s*,[\s\S]*?<\/cfquery>