匹配右括号的正则表达式不在引号中

时间:2013-03-06 16:40:39

标签: .net regex

我正在尝试构建匹配字符串的正则表达式,如

1.) $(Something)
2.) $(SomethingElse, ")")
3.) $(SomethingElse, $(SomethingMore), Bla)
4.) $$(NoMatch) <-- should not match
5.) $$$(ShouldMatch) <-- so basically $$ will produce $

在文本中。

编辑:单词Something,SomethingElse,NoMatch,ShouldMatch甚至可以是其他单词 - 它们是宏的名称。我试图匹配的字符串是“宏调用”,它可以出现在文本中,应该用它们的结果替换。我需要正则表达式只是为了语法高亮。应突出显示完整的宏调用。 3号目前不是那么重要。需要1号和2号才能工作。如果数字4和5不能像上面所写的那样工作,但$(之后的任何$都不匹配,那就没问题了。

目前我有

(?<!\$)+\$\(([^)]*)\)

如果没有前导$(,哪个匹配任何$,如果我找不到另一种方法来应用$$结构,那么这可能没问题。

我想要完成的下一步是忽略结束括号,如果它在引号中。我怎么能做到这一点?

编辑这样,如果我有像

这样的输入
Some text, doesn't matter what. And a $(MyMacro, ")") which will be replaced.

完整的'$(MyMacro, ")")'会突出显示。

我已经有了这个表达

"(?:\\\\|\\"|[^"])*"

用于报价,包括转义报价。但我不知道如何应用这种方式来忽略它们之间的一切......

P.S。我正在使用.NET来应用正则表达式。这样平衡的团体将得到支持。我只是不知道如何应用这一切。

5 个答案:

答案 0 :(得分:4)

你可以使用这样的表达式:

(?<! \$ )                     # not preceded by $
\$ (?: \$\$ )?                # $ or $$$
\(                            # opening (

(?>                           # non-backtracking atomic group
  (?>                         # non-backtracking atomic group
    [^"'()]+                  # literals, spaces, etc
  | " (?: [^"\\]+ | \\. )* "  # double quoted string with escapes
  | ' (?: [^'\\]+ | \\. )* '  # single quoted string with escapes
  | (?<open>       \( )       # open += 1
  | (?<close-open> \) )       # open -= 1, only if open > 0 (balancing group)
  )*
)

(?(open) (?!) )               # fail if open > 0

\)                            # final )

可以如上所述引用。例如在C#中:

var regex = new Regex(@"(?x)    # enable eXtended mode (ignore spaces, comments)
(?<! \$ )                       # not preceded by $
\$ (?: \$\$ )                   # $ or $$$
\(                              # opening (

(?>                             # non-backtracking atomic group
  (?>                           # non-backtracking atomic group
    [^""'()]+                   # literals, spaces, etc
  | "" (?: [^""\\]+ | \\. )* "" # double quoted string with escapes
  | '  (?: [^'\\]+ | \\. )*  '  # single quoted string with escapes
  | (?<open>       \( )         # open += 1
  | (?<close-open> \) )         # open -= 1, only if open > 0 (balancing group)
  )*
)

(?(open) (?!) )                 # fail if open > 0

\)                              # final )
");

答案 1 :(得分:1)

对于将宏作为参数(1和2)作为参数输出的部分,您可以执行以下操作:

(?<!\$)+\$\(([^)]*?("[^"]*?")?)+\)

您可以在此处查看here

在宏(3)的情况下,您可以这样做:

(?<!\$)+\$\(([^)]*?("[^"]*?")?(\$\([^)]*?\))?)+\)

但这不适用于包含字符串括号括号的宏。

您可以看到结果here

答案 2 :(得分:1)

这样的事情很复杂......所以不要害怕以下事情:

RegEx:(?<!\$)(?:\$\$)*(\$\((?:[\w, ]+|(?>"(?:(?<=\\)"|[^"])+")|(?1)+)*\))
在此解释演示:http://regex101.com/r/yZ5dI7

这跟随所有5个点,将匹配前3个宏类型,甚至更多与"或宏 - 内 - 宏的更深层次的变化,只有当它前面的$数为奇数时。

答案 3 :(得分:0)

我最近一直在寻找类似的正则表达式,但是我决定使用C#解析文本比使用正则表达式更快,因为我的正则表达式技能很差...所以我写了this method来删除Razor代码块

您可以轻松修改它以满足您的需求而无需复杂的正则表达式

答案 4 :(得分:0)

你的意思是这样的吗?

\$\(SomethingElse, \"|[^"\)]?\"\)