Find a pattern to match 'a', ignoring that

2020-04-20 03:04发布

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:)

2条回答
乱世女痞
2楼-- · 2020-04-20 03:44

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)"))
查看更多
贼婆χ
3楼-- · 2020-04-20 03:55

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");
查看更多
登录 后发表回答