【问题标题】:Find a pattern to match 'a', ignoring that 'a' which lies within 'b' and 'c'查找匹配“a”的模式,忽略位于“b”和“c”之间的“a”
【发布时间】:2012-08-17 06:31:32
【问题描述】:

需要复合表达式

" from" such that " from" is not within parenthesis

(忽略括号中的)这里a=" from"; b="("; and c=")";

我能写的最接近(但无效)的模式是

string pat = @"^((?!\(.* from.*\)).)* from((?!\(.* from.*\)).)*$";

我的表达否认括号中是否存在任何“来自”,但我想严格忽略这样的“来自”


应在以下位置找到匹配项:

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

不包含匹配项的字符串:(因为我想忽略括号内的“from”)

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




相关资料:(没必要阅读)

最接近我的问题的最有用的链接告诉我如何匹配“模式”而不是“常规”是 stanav 在 2009 年 7 月 31 日上午 8:05 在以下链接中的回复...

http://www.vbforums.com/archive/index.php/t-578417.html

还有:Regex in C# that contains "this" but not "that

还有:Regular expression to match a line that doesn't contain a word?

我已经学习/搜索了大约一周,但对我来说仍然很复杂:)

【问题讨论】:

  • 括号可以嵌套吗?
  • 是的,即使它们可以嵌套。但我只需要找到不在任何括号中的“来自”。如果找到了。表达式匹配
  • 对于 SQL,您需要一个解析器。对于“hello bro!Whats up”,您也许可以使用正则表达式。
  • 我不知道 .NET 的正则表达式是否可以处理嵌套模式,Perl 可以是“递归的”AFAIK。
  • @HenkHolterman。是的,表达式是可变的

标签: c# regex pattern-matching


【解决方案1】:

即使使用任意嵌套的括号,以下内容也应该有效:

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

如果您坚持,作为单行正则表达式(“恐怖!恐怖!”):

if (Regex.IsMatch(subjectString,@"\sfrom(?=(?:[^()]*\((?>[^()]+|\((?<DEPTH>)|\)(?<-DEPTH>))*(?(DEPTH)(?!))\))*[^()]*\z)"))

【讨论】:

  • !请在底部写下不带 cmets 的单行表达式,因为我可能会在重写时遇到错误。
  • 什么是深度?我以前从未见过它。它是一个特殊的词还是变量? \z 应该在 C# 中替换为 $?
  • @SamiAkram:它是一个变量。 \z$ 更具体(它实际上只匹配字符串的末尾,而不是任何结束空格之前,这就是我通常更喜欢它的原因),但在这种情况下,你也可以使用 @987654325 @.
  • string q = "select hi from t1 in (select hello from t2)"; If(Regex.IsMatch(q, @"\sfrom(?(?:[^()]*((?>[^()]+|( (?)|) (?) )*(?(DEPTH)(?!))))*[^()]*\z)", RegexOptions.IgnorePatternWhitespace)) 出错:解析错误。量词 {x,y} 无后缀
  • @SamiAkram:看起来你在复制正则表达式时丢失了很多反斜杠。此外,该错误没有多大意义 - 此正则表达式中的任何地方都没有 {x,y} 量词。
【解决方案2】:

这可能是你想要的。

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

【讨论】:

  • 是的,阿尼鲁达。你解决了我的问题。谢谢你。我用过类似的东西。它正在解决我目前的问题。但不是标题的解决方案,因为如果我得到解决方案 'a' 忽略 'b' 中的 'a',我可以忽略标准,因为 'bb hj exp ab' 忽略由 'bb.*exp.*ab' 包围的任何 exp。它将是任意两个表达式的某种组合,并动态地适用于新情况。无论如何,你解决了我的问题,比我做得更好,所以我支持你。非常感谢。也欢迎任何进一步的帮助。
  • 嵌套括号失败。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-04
  • 2012-06-26
  • 2017-12-24
  • 1970-01-01
相关资源
最近更新 更多