Reputation: 4461
I have string
var statement="ROUND(CDBL('0'),2)=ROUND((CDBL('0.00')*CDBL('0')/100),2)"
and I have regex
@"[ROUND^]+\(\w+\([\'^].*?[\']\)+[\,]+[\d]+\)|[ROUND^]+\(+[\']+.+[\']+[\,]+[\d]+\)"
from that string I want to search from my regex all ROUND functions like below:
MatchCollection roundFunctions = Regex.Matches(statement, @"[ROUND^]+\(\w+\([\'^].*?[\']\)+[\,]+[\d]+\)|[ROUND^]+\(+[\']+.+[\']+[\,]+[\d]+\)");
From MatchCollection result I got only one match. I'm expecting two matches since my string has two ROUND functions. Is there missing on my regex? Please help. I'm not good in regex.
Updated:
Here's the screenshot from online regex. As you can see only the first ROUND function has been matched. I need to get the second ROUND function too.
Updated:
To be clearer what output for the following regex I'm expecting.
[ROUND^]+\(\w+\([\'^].*?[\']\)+[\,]+[\d]+\)|[ROUND^]+\(+[\']+.+[\']+[\,]+[\d]+\)
Currently it matches only for the following strings:
I want that regex to match also the following
Please help.
Upvotes: 0
Views: 111
Reputation: 1069
I would recommend a tool like gplex/gppg, GOLD, ANTLR to do this kind of work, especially since you will be evaluating the parsed result.
If you insist on using .NET RegEx, I suggest you have a look at using Balancing Group Definitions.
If you want something a little easier to deal with, then I would consider writing a simple Recursive Descent Parser to break your input down into a syntax tree, then evaluate it. Wikipedia has a decent sample written in C (without pointers so it is easy to convert to .net) which I have copied below as well.
Balancing Group Sample
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>
Recursive Descent Parser Sample (from 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);
}
Upvotes: 2