【问题标题】:Regular Expression - Match End if Start is Match正则表达式 - 如果开始匹配则匹配结束
【发布时间】:2015-07-06 23:15:02
【问题描述】:

我要匹配以下字符串:

[anything can be here]
[{anything can be here}]

我可以只使用一个正则表达式来实现吗?

我目前正在使用这个'^\[({)?.+(})?]$',但它也会匹配:

[anything can be here}]
[{anything can be here]

只有在使用{ 时,我才需要匹配}

请注意,我只能使用正则表达式匹配函数,因为我已将其实现为 SQL CLR 函数,以便在 T-SQL 语句中使用它。

【问题讨论】:

    标签: c# sql .net regex tsql


    【解决方案1】:

    基本上你可以写(逐字字符串):

    ^\[(?:{.+}|[^]{}]+)]$
    

    你可以使用更复杂的条件语句(?(condition)then|else)

    ^\[({)?[^]{}]+(?(1)}|)]$
    

    (如果捕获组 1 存在,则 } 否则没有)

    但这种方式可能效率较低。

    【讨论】:

    • 条件语句中甚至不需要|,只需^\[({)?[^]{}]+(?(1)})]$就足够了(只有yes部分)。
    • @stribizhev:确实,这只是为了说明条件结构。但正如我所说,使用这种方式是大材小用,仅供参考。
    【解决方案2】:

    我得到了这个工作:\[[^{].*[^}]\]|\[\{.*\}\]

    编辑 正如 OP 所指出的,括号之间需要有一些东西,所以“一个或多个”匹配更合适:

    \[[^{].+[^}]\]|\[\{.+\}\]

    see RegEx example here

    【讨论】:

      【解决方案3】:

      您的正则表达式 ^\[({)?.+(})?]$ 将仅匹配单个字符串,例如 [{...}][{...],因为 1) 您有锚点 (^$),并且两个花括号以相同的模式出现。

      我建议使用否定的look-behinds 来避免匹配[]-ed 字符串中只有一个大括号的字符串,如下所示:

      var rgx = new Regex(@"((?!\[\{[^}]+\]|\[[^{]+\})\[\{?.+?\}?\])");
      var tst = "[anything can be here] [{anything can be here}] [anything can be here}] [{anything can be here]";
      var mtch = rgx.Matches(tst).Cast<Match>().ToList();
      

      即使在更大的上下文中,这也将确保您匹配 []-ed 字符串。

      结果:

      【讨论】:

        【解决方案4】:

        试试这个:

        \[[^{].*[^}]\]|\[[^{}]\]|\[\{.+\}\]

        当分解时匹配 3 种类型的字符串:

        1. [] 包围 ≥ 2 个字符,前提是第一个字符不是 {,最后一个字符不是 }
        2. [{}] 包围任何东西
        3. [] 包围单个非大括号字符(以前的答案未涵盖的边缘情况)

        【讨论】:

        • 我认为它不能正常工作。 1)太贪婪,2)匹配不需要的情况。见goo.gl/9dlTyX
        【解决方案5】:

        好的,我知道这个问题已经得到解答,但我想我会展示一个纯 T-SQL 解决方案作为替代方案。

        DECLARE @yourTable TABLE (val VARCHAR(100));
        INSERT INTO @yourTable
            VALUES  ('[anything can be here]'),
                    ('[{anything can be here}]'),
                    ('[anything can be here}]'),
                    ('[{anything can be here]');
        
        WITH CTE_Brackets
        AS
        (
            SELECT  val,
                    CASE 
                        WHEN CHARINDEX('{',val) > 0 THEN CHARINDEX('{',val)
                    END  AS L_curly,
                    CASE 
                        WHEN CHARINDEX('}',val) > 0 THEN CHARINDEX('}',val)
                    END AS R_curly,
        
                    CASE 
                        WHEN CHARINDEX('[',val) > 0 THEN CHARINDEX('[',val)
                    END  AS L_bracket,
                    CASE 
                        WHEN CHARINDEX(']',val) > 0 THEN CHARINDEX(']',val)
                    END  AS R_bracket
            FROM @yourTable
        ),
        CTE_string
        AS
        (
            SELECT  val,
                    L_curly,
                    R_curly,
                    L_bracket,
                    R_bracket,
                    SUBSTRING(val,start_pos,end_pos - start_pos) val_string
            FROM CTE_Brackets A
            CROSS APPLY (SELECT COALESCE(L_curly,L_bracket) + 1 AS start_pos,
                                COALESCE(R_curly,R_bracket)     AS end_pos
                        ) CA
        )
        
        SELECT A.val,B.val
        FROM CTE_string A
        INNER JOIN CTE_string B
            ON A.val_string = B.val_string
            AND
            (
                (
                            A.L_curly IS NOT NULL
                        AND A.R_curly IS NULL
                        AND B.L_curly IS NULL
                        AND B.R_curly IS NOT NULL
                ) --left curly matching right only curly
                OR 
                (
                            A.L_curly + A.R_curly IS NOT NULL
                        AND B.R_curly IS NULL
                        AND B.L_curly IS NULL
                ) --matches both curly to no curly
            )
        ORDER BY B.val
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-02-06
          • 1970-01-01
          • 1970-01-01
          • 2022-07-05
          • 2012-04-14
          • 2022-12-11
          • 2016-11-10
          相关资源
          最近更新 更多