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

时间:2015-04-28 08:05:03

标签: c# sql .net regex tsql

我想匹配以下字符串:

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

我是否可以仅使用一个正则表达式实现此目的?

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

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

仅在使用}时才需要匹配{

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

5 个答案:

答案 0 :(得分:4)

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

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

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

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

(如果存在捕获组1,那么}则不存在)

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

答案 1 :(得分:2)

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

我建议使用负面的后台来避免匹配[] - ed字符串中只有1个大括号的字符串,如下所示:

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字符串,即使在更大的上下文中也是如此。

结果:

enter image description here

答案 2 :(得分:2)

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

修改 OP指出的需要在括号之间进行,因此“一个或多个”匹配更适合:

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

see RegEx example here

答案 3 :(得分:1)

试试这个:

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

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

  1. []周围≥2个字符,前提是第一个字符不是{而最后一个字符不是}
  2. [{}]围绕任何事情
  3. []围绕一个非大括号字符(前一个答案未涵盖的边缘案例)

答案 4 :(得分:0)

好的,我知道这个问题已经得到解答,但我认为我会展示一个纯粹的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