2015-04-28 8 views
5

Chcę dopasować następujące ciągi:Regular Expression - Mecz Koniec jeśli start jest mecz

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

można to osiągnąć za pomocą tylko jednego wyrażenia regularnego?

Obecnie używam tego jednego '^\[({)?.+(})?]$', ale będzie pasować również:

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

muszę dopasować } tylko wtedy, gdy jest używany {.

Proszę zauważyć, że mogę używać tylko funkcji dopasowania wyrażenia regularnego, ponieważ zaimplementowałem ją jako funkcję SQL CLR w celu użycia jej w instrukcjach T-SQL.

Odpowiedz

2

dostałem tej pracy: \[[^{].*[^}]\]|\[\{.*\}\]

EDIT jak podkreślił OP coś musi być w nawiasie tak jest 'jeden lub więcej' mecz bardziej nadaje się:

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

see RegEx example here

2

Twój regex ^\[({)?.+(})?]$ będzie pasował tylko indywidualny ciąg jak [{...}] lub [{...] ponieważ 1) masz kotwic (^$), a oba nawiasy klamrowe są obecne w tym samym wzorem.

Proponuję za pomocą negatywnych przeglądowej tyłki uniknąć dopasowania ciągów, które właśnie 1 nawias klamrowy wewnątrz [] -ED ciąg jak ten:

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(); 

Będzie to upewnij się, że pasuje do [] -ED nawet w ciągi większy kontekst.

Wynik:

enter image description here

4

W zasadzie można napisać (verbatim strings):

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

Można użyć czegoś bardziej skomplikowanego z warunkowym rachunku (?(condition)then|else):

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

(jeżeli grupa przechwytywania 1 istnieje, następnie } inaczej nic)

Ale ten sposób jest prawdopodobnie mniej wydajny.

+1

Nie trzeba nawet '| {(' w rachunku warunkowym, po prostu '^ \ [()? (1))? [^] {}] +}] $' Wystarczy (z tak tylko część). –

+0

@stribizhev: Rzeczywiście, to tylko po to, aby zilustrować strukturę warunkową. Ale jak powiedziałem, używanie tego sposobu jest przesadą, to tylko dla informacji. –

1

Spróbuj tego:

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

który po podziale meczów 3 rodzaje sznurka:

  1. [] otaczające ≥ 2 znaki pod warunkiem, że pierwszy znak nie jest { i ISN ostatni znak "t }
  2. [{}] otaczające wszystko
  3. [] otaczających pojedynczy non charakter nawias klamrowy (AN przypadek krawędzi nieobjętych poprzednimi odpowiedziami)
+0

Nie sądzę, że działa poprawnie. Jest 1) zbyt chciwy, 2) dopasowuje niechciane przypadki. Zobacz http://goo.gl/9dlTyX –

0

Dobrze wiem, że to pytanie zostało odebrane, ale pomyślałem, że wykazują czystego roztworu T-SQL tylko jako alternatywny.

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