我有字符串
var statement="ROUND(CDBL('0'),2)=ROUND((CDBL('0.00')*CDBL('0')/100),2)"
我有正则表达式
@"[ROUND^]+\(\w+\([\'^].*?[\']\)+[\,]+[\d]+\)|[ROUND^]+\(+[\']+.+[\']+[\,]+[\d]+\)"
从该字符串我想从我的正则表达式中搜索所有ROUND函数,如下所示:
MatchCollection roundFunctions = Regex.Matches(statement, @"[ROUND^]+\(\w+\([\'^].*?[\']\)+[\,]+[\d]+\)|[ROUND^]+\(+[\']+.+[\']+[\,]+[\d]+\)");
从MatchCollection结果我只得到一个匹配。因为我的字符串有两个ROUND函数,所以我期待两个匹配。我的正则表达式上有缺失吗?请帮忙。我在正则表达方面不擅长。
更新:
以下是在线正则表达式的截图。正如您所看到的,只有第一个ROUND函数匹配。我也需要获得第二个ROUND函数。
更新:
更清楚我期待的以下正则表达式的输出。
[ROUND^]+\(\w+\([\'^].*?[\']\)+[\,]+[\d]+\)|[ROUND^]+\(+[\']+.+[\']+[\,]+[\d]+\)
目前仅与以下字符串匹配:
我希望该正则表达式与以下
相匹配请帮忙。
答案 0 :(得分:2)
我建议使用像gplex / gppg,GOLD,ANTLR这样的工具来完成这类工作,特别是因为您将评估解析后的结果。
如果您坚持使用.NET RegEx,我建议您查看使用Balancing Group Definitions。
如果你想要一些更容易处理的东西,那么我会考虑编写一个简单的Recursive Descent Parser来将输入分解为语法树,然后对其进行评估。维基百科有一个很好的用C语言编写的示例(没有指针,因此很容易转换为.net),我也在下面复制过。
平衡小组样本
using System;
using System.Text.RegularExpressions;
class Example
{
public static void Main()
{
string pattern = "^[^<>]*" +
"(" +
"((?'Open'<)[^<>]*)+" +
"((?'Close-Open'>)[^<>]*)+" +
")*" +
"(?(Open)(?!))$";
string input = "<abc><mno<xyz>>";
Match m = Regex.Match(input, pattern);
if (m.Success == true)
{
Console.WriteLine("Input: \"{0}\" \nMatch: \"{1}\"", input, m);
int grpCtr = 0;
foreach (Group grp in m.Groups)
{
Console.WriteLine(" Group {0}: {1}", grpCtr, grp.Value);
grpCtr++;
int capCtr = 0;
foreach (Capture cap in grp.Captures)
{
Console.WriteLine(" Capture {0}: {1}", capCtr, cap.Value);
capCtr++;
}
}
}
else
{
Console.WriteLine("Match failed.");
}
}
}
// The example displays the following output:
// Input: "<abc><mno<xyz>>"
// Match: "<abc><mno<xyz>>"
// Group 0: <abc><mno<xyz>>
// Capture 0: <abc><mno<xyz>>
// Group 1: <mno<xyz>>
// Capture 0: <abc>
// Capture 1: <mno<xyz>>
// Group 2: <xyz
// Capture 0: <abc
// Capture 1: <mno
// Capture 2: <xyz
// Group 3: >
// Capture 0: >
// Capture 1: >
// Capture 2: >
// Group 4:
// Group 5: mno<xyz>
// Capture 0: abc
// Capture 1: xyz
// Capture 2: mno<xyz>
递归下降解析器样本(来自Wikipedia)
typedef enum {ident, number, lparen, rparen, times, slash, plus,
minus, eql, neq, lss, leq, gtr, geq, callsym, beginsym, semicolon,
endsym, ifsym, whilesym, becomes, thensym, dosym, constsym, comma,
varsym, procsym, period, oddsym} Symbol;
Symbol sym;
void getsym(void);
void error(const char msg[]);
void expression(void);
int accept(Symbol s) {
if (sym == s) {
getsym();
return 1;
}
return 0;
}
int expect(Symbol s) {
if (accept(s))
return 1;
error("expect: unexpected symbol");
return 0;
}
void factor(void) {
if (accept(ident)) {
;
} else if (accept(number)) {
;
} else if (accept(lparen)) {
expression();
expect(rparen);
} else {
error("factor: syntax error");
getsym();
}
}
void term(void) {
factor();
while (sym == times || sym == slash) {
getsym();
factor();
}
}
void expression(void) {
if (sym == plus || sym == minus)
getsym();
term();
while (sym == plus || sym == minus) {
getsym();
term();
}
}
void condition(void) {
if (accept(oddsym)) {
expression();
} else {
expression();
if (sym == eql || sym == neq || sym == lss || sym == leq || sym == gtr || sym == geq) {
getsym();
expression();
} else {
error("condition: invalid operator");
getsym();
}
}
}
void statement(void) {
if (accept(ident)) {
expect(becomes);
expression();
} else if (accept(callsym)) {
expect(ident);
} else if (accept(beginsym)) {
do {
statement();
} while (accept(semicolon));
expect(endsym);
} else if (accept(ifsym)) {
condition();
expect(thensym);
statement();
} else if (accept(whilesym)) {
condition();
expect(dosym);
statement();
} else {
error("statement: syntax error");
getsym();
}
}
void block(void) {
if (accept(constsym)) {
do {
expect(ident);
expect(eql);
expect(number);
} while (accept(comma));
expect(semicolon);
}
if (accept(varsym)) {
do {
expect(ident);
} while (accept(comma));
expect(semicolon);
}
while (accept(procsym)) {
expect(ident);
expect(semicolon);
block();
expect(semicolon);
}
statement();
}
void program(void) {
getsym();
block();
expect(period);
}