问题
Need a compound expression for
" from" such that " from" is not within parenthesis
(ignoring those which are in parenthesis) here a=" from"; b="("; and c=")";
The closest (but invalid) pattern I could write is
string pat = @"^((?!\(.* from.*\)).)* from((?!\(.* from.*\)).)*$";
my expression denies if any " from" is present in parenthesis but i want to strictly ignore such " from"
Matches should be found in:
1: " from" 2:select field1 from t1 (select field1 from t1) ---- 1 time in both
3: select field1 from t1 (select field1 from t1)select field1 from t1 ---2 times
Strings not containing matches:(Because i want to ignore the " from" within parenthesis)
1: select field1 no_f_rom_OutOf_Parenthesis t1 (select field1 from t1)
2: (select field1 from t1) 3: "" (Empty String) 4. No word as form
0 times in all four strings
Relevant Material: (not much necessary to read)
The most helpful link nearer to my question telling how to match 'pattern' but not 'regular' has been a reply by stanav at Jul 31st, 2009, 08:05 AM in following link...
http://www.vbforums.com/archive/index.php/t-578417.html
Also: Regex in C# that contains "this" but not "that
Also: Regular expression to match a line that doesn't contain a word?
I have studied/searched about a week but still Its complex for me:)
回答1:
The following should work, even with arbitrarily nested parentheses:
if (Regex.IsMatch(subjectString,
@"\sfrom # Match ' from'
(?= # only if the following regex can be matched here:
(?: # The following group, consisting of
[^()]* # any number of characters except parentheses,
\( # followed by an opening (
(?> # Now match...
[^()]+ # one or more characters except parentheses
| # or
\( (?<DEPTH>) # a (, increasing the depth counter
| # or
\) (?<-DEPTH>) # a ), decreasing the depth counter
)* # any number of times
(?(DEPTH)(?!)) # until the depth counter is zero again,
\) # then match the closing )
)* # Repeat this any number of times.
[^()]* # Then match any number of characters except ()
\z # until the end of the string.
) # End of lookahead.",
RegexOptions.IgnorePatternWhitespace))
As a single line regex ("The horror! The horror!"), if you insist:
if (Regex.IsMatch(subjectString,@"\sfrom(?=(?:[^()]*\((?>[^()]+|\((?<DEPTH>)|\)(?<-DEPTH>))*(?(DEPTH)(?!))\))*[^()]*\z)"))
回答2:
This may be what you want.
string s="select field1 dfd t1 (select field1 from t1)select field1 from t1";
Regex r=new Regex(@"(?<=\)|^)\bselect\b.*?\bfrom\b.*?(?=\()",RegexOptions.RightToLeft);
r.Replace(s,"HELL yeah");
来源:https://stackoverflow.com/questions/12000821/find-a-pattern-to-match-a-ignoring-that-a-which-lies-within-b-and-c