Regular expression - the end of the match, if the beginning of the match

I want to match the following lines:

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

Can I achieve this using only one regular expression?

I am currently using this '^\[({)?.+(})?]$' , But it will also match:

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

I need to match } only if { used.

Please note that I can only use the regular expression matching function, since I implemented it as a SQL CLR function to use it in T-SQL .

+5
source share
5 answers

I got this work: \[[^{].*[^}]\]|\[\{.*\}\]

CHANGE as indicated by OP, something must be between the parentheses, so “one or more” matches are more suitable:

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

see here RegEx example

+2
source

Basically you can write (shorthand lines):

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

You can use something more complex with a conditional statement (?(condition)then|else) :

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

(if capture group 1 exists, then else } nothing)

But this method is probably less effective.

+4
source

Your regular expression ^\[({)?.+(})?]$ Will only match a single line, for example [{...}] or [{...] , because 1) you have bindings ( ^$ ), and both curly braces are present in the same pattern.

I suggest using a negative look to avoid matching lines that only have 1 braces inside the [] -ed line, like this:

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

This will allow you to match [] -ed strings even in a wider context.

Result:

enter image description here

+2
source

Try the following:

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

What when splitting corresponds to 3 line types:

  • [] surrounding ≥ 2 characters if the first character is not { and the last character is not }
  • [{}] surrounding something
  • [] surrounding one curly brace (extreme case not covered by previous answers)
+1
source

Well, I know that this question was answered, but I thought that I would show a clean T-SQL solution as an alternative.

 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 
0
source

All Articles