我正在尝试创建一个.NET RegEx表达式,它将正确地平衡我的括号。我有以下RegEx表达式:
func([a-zA-Z_][a-zA-Z0-9_]*)\(.*\)
我想要匹配的字符串是:
"test -> funcPow((3),2) * (9+1)"
应该发生什么是正则表达式应匹配从funcPow
到第二个右括号的所有内容。它应该在第二个右括号后停止。相反,它一直匹配到最后一个右括号。 RegEx将此返回:
"funcPow((3),2) * (9+1)"
它应该返回:
"funcPow((3),2)"
对此有任何帮助将不胜感激。
答案 0 :(得分:49)
正则表达式绝对可以做平衡括号匹配。它可能很棘手,需要一些更高级的Regex功能,但它并不太难。
示例:
var r = new Regex(@"
func([a-zA-Z_][a-zA-Z0-9_]*) # The func name
\( # First '('
(?:
[^()] # Match all non-braces
|
(?<open> \( ) # Match '(', and capture into 'open'
|
(?<-open> \) ) # Match ')', and delete the 'open' capture
)+
(?(open)(?!)) # Fails if 'open' stack isn't empty!
\) # Last ')'
", RegexOptions.IgnorePatternWhitespace);
平衡匹配组有几个功能,但对于此示例,我们仅使用捕获删除功能。行(?<-open> \) )
将匹配)
并删除之前的“打开”捕获。
最棘手的一句话是(?(open)(?!))
,所以让我解释一下。 (?(open)
是一个条件表达式,仅在存在“打开”捕获时才匹配。 (?!)
是一个总是失败的否定表达式。因此,(?(open)(?!))
表示“如果有开放捕获,则失败”。
答案 1 :(得分:19)
使用平衡组,它是:
Regex rx = new Regex(@"func([a-zA-Z_][a-zA-Z0-9_]*)\(((?<BR>\()|(?<-BR>\))|[^()]*)+\)");
var match = rx.Match("funcPow((3),2) * (9+1)");
var str = match.Value; // funcPow((3),2)
(?<BR>\()|(?<-BR>\))
是Balancing Group(BR
我用的名称是Brackets
)。以这种方式更清楚 (?<BR>
\( )|(?<-BR>
<强大> \) )
也许,以便\(
和{ {1}}更“明显”。
如果你真的讨厌自己(以及这个世界/你的同伴共同编程)足以使用这些东西,我建议到处使用\)
和“洒”白色空间: - )
答案 2 :(得分:0)
正则表达式仅适用于Regular Languages。这意味着正则表达式可以找到“a和b的任意组合”的类型。(ab
或babbabaaa
等)但是他们找不到“ n a,一个b, n a的“。(a^n b a^n
)正则表达式不能保证第一组a匹配第二组a。
因此,它们无法匹配相同数量的开括号和右括号。编写一个一次遍历字符串一个字符的函数就很容易了。有两个柜台,一个用于打开paren,一个用于关闭。如果opening_paren_count != closing_parent_count
返回false,则在遍历字符串时递增指针。
答案 3 :(得分:-1)
func[a-zA-Z0-9_]*\((([^()])|(\([^()]*\)))*\)
您可以使用它,但如果您正在使用.NET,则可能有更好的替代方案。
这部分你已经知道了:
func[a-zA-Z0-9_]*\( --weird part-- \)
- 奇怪的部分 - 部分只是意味着; (
允许任何字符.
或|
任何部分(.*)
按其所需的次数)*
存在。唯一的问题是,您无法匹配任何字符.
,您必须使用[^()]
来排除括号。
(([^()])|(\([^()]*\)))*