簡體   English   中英

正則表達式 - 如果開始匹配則匹配結束

[英]Regular Expression - Match End if Start is Match

我想匹配以下字符串:

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

我只能使用一個正則表達式來實現這一點嗎?

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

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

我需要匹配}只有{使用}

請注意,我只能使用正則表達式匹配函數,因為我已將其實現為SQL CLR函數,以便在T-SQL語句中使用它。

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

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

您可以使用更復雜的條件語句(?(condition)then|else)

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

(如果存在捕獲組1,那么}否則什么都沒有)

但這種方式可能效率較低。

你的正則表達式^\\[({)?.+(})?]$只匹配一個單獨的字符串,如[{...}][{...]因為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字符串。

結果:

在此輸入圖像描述

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

OP指出的 編輯 需要在括號之間進行,因此“一個或多個”匹配更適合:

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

請參閱此處的RegEx示例

試試這個:

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

當細分時匹配3種類型的字符串:

  1. []周圍≥2個字符,前提是第一個字符不是{而最后一個字符不是}
  2. [{}]圍繞着任何東西
  3. []圍繞一個非大括號字符(前一個答案未涵蓋的邊緣案例)

好的,我知道這個問題已經得到解答,但我認為我會展示一個純粹的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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM