正则表达式 - 如果开始匹配则匹配结束

Posted

技术标签:

【中文标题】正则表达式 - 如果开始匹配则匹配结束【英文标题】: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 语句中使用它。

【问题讨论】:

【参考方案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 种类型的字符串:

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

【讨论】:

我认为它不能正常工作。 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

【讨论】:

以上是关于正则表达式 - 如果开始匹配则匹配结束的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式

正则表达式

正则表达式

如何用正则表达式匹配指定字符开始和指定字符结束?

正则表达式

正则表达式-语法