正则表达式查找所有搜索关键字匹配

时间:2015-03-03 04:02:59

标签: regex c#-4.0

我有字符串

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函数。

http://regexhero.net/tester/ http://regexhero.net/tester/

更新:

更清楚我期待的以下正则表达式的输出。

[ROUND^]+\(\w+\([\'^].*?[\']\)+[\,]+[\d]+\)|[ROUND^]+\(+[\']+.+[\']+[\,]+[\d]+\)

目前仅与以下字符串匹配:

  1. ROUND(CDBL( '0'),2)
  2. ROUND(CDBL( '1'),2)+ ROUND(CDBL( '3'),2)
  3. ROUND(CDBL( '4.25'),3)* ROUND(CDBL( '5.76'),4)
  4. ROUND(CDBL('20 0.3 '),2)/ ROUND(CDBL('10'),2)
  5. ROUND(CDBL( '100.55'),2)-round(CDBL('10 0.2' ),2)
  6. 我希望该正则表达式与以下

    相匹配
    1. ROUND((CDBL( '00年5月24日')* CDBL( '7.4')/ 100),2)
    2. ROUND((CDBL( '300.45.00') - CDBL( '100.4')/ 100),2)
    3. 请帮忙。

1 个答案:

答案 0 :(得分:2)

我建议使用像gplex / gppgGOLD,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);
}