正则表达式模式匹配不能递归地工作

时间:2012-04-18 03:42:32

标签: java regex

我想以

的形式实现模式匹配

(A + B)(C-或*或/ d).............. 在任何一次。

我使用以下模式,但它不能递归地工作。 它只是阅读第一组。

Pattern pattern;
String regex="(([0-9]*)([+,-,/,*])([0-9]*)*)";
pattern=Pattern.compile(regex);
Matcher match = pattern.matcher(userInput);

4 个答案:

答案 0 :(得分:0)

你需要一个像这样的表达式

[0-9]+-[0-9]+[\/*-+][0-9]+[\/*-+][0-9]+[\/*-+][0-9]+[\/*-+][0-9]+

你必须匹配整个表达式。您无法匹配表达式的一部分并进行第二次搜索,因为重复了模式。

注意:在ruby \中是/字符的excape序列,所以你可以在C#中省略它或用另一个characer替换它。

Demo

答案 1 :(得分:0)

模式

<!--
\((\d|[\+\-\/\\\*\^%!]+|(or|and) *)+\)

Options: ^ and $ match at line breaks

Match the character “(” literally «\(»
Match the regular expression below and capture its match into backreference number 1 «(\d|[\+\-\/\\\*\^%!]+|(or|and) *)+»
   Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
   Note: You repeated the capturing group itself.  The group will capture only the last iteration.  Put a capturing group around the repeated group to capture all iterations. «+»
   Match either the regular expression below (attempting the next alternative only if this one fails) «\d»
      Match a single digit 0..9 «\d»
   Or match regular expression number 2 below (attempting the next alternative only if this one fails) «[\+\-\/\\\*\^%!]+»
      Match a single character present in the list below «[\+\-\/\\\*\^%!]+»
         Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
         A + character «\+»
         A - character «\-»
         A / character «\/»
         A \ character «\\»
         A * character «\*»
         A ^ character «\^»
         One of the characters “%!” «%!»
   Or match regular expression number 3 below (the entire group fails if this one fails to match) «(or|and) *»
      Match the regular expression below and capture its match into backreference number 2 «(or|and)»
         Match either the regular expression below (attempting the next alternative only if this one fails) «or»
            Match the characters “or” literally «or»
         Or match regular expression number 2 below (the entire group fails if this one fails to match) «and»
            Match the characters “and” literally «and»
      Match the character “ ” literally « *»
         Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match the character “)” literally «\)»
-->

计算算法
要解析和处理输入字符串,您必须使用堆栈。请访问here了解相关概念。

问候
Cylian

答案 2 :(得分:0)

您需要匹配这种序列的正则表达式是:

\s*-?\d+(?:\s*[-+/*]\s*-?\d+)+\s*

让我们把它分解为它的组成部分!

\s*            # Optional space
-?             # Optional minus sign
\d+            # Mandatory digits
(?:            # Start sub-regex
   \s*         #    Optional space
   [-+*/]      #    Mandatory single arithmetic operator
   \s*         #    Optional space
   -?          #    Optional minus sign
   \d+         #    Mandatory digits
)+             # End sub-regex: want one or more matches of it
\s*            # Optional space

(如果你不想匹配空格,请删除所有\s*,并注意它会给用户带来很多惊喜。)

现在,在Java中编译上述字符串文字时(编译前),您需要小心地转义其中的每个\字符:

String regex="\\s*-?\\d+(?:\\s*[-+/*]\\s*-?\\d+)+\\s*";

要注意的另一件事是, 将正则表达式分成几部分,以便Java解析并构建表达式评估树;它只是(与你的其余代码)匹配整个字符串或不。 (即使放入捕获括号也没有多大帮助;当放入某种形式的重复时,它们只报告它们匹配的字符串中的第一个位置。)正确执行此操作的最简单方法是使用类似的解析器生成器Antlr(它还可以让你做括号子表达式,管理运算符优先级等等)。

答案 3 :(得分:-1)

你的表达不会逃脱像+,(,)

这样的特殊字符

试试这个

/\(\d+[\+|-|\/|\*]\d+)\G?/

\ G再次是整个模式

?意味着前一个是可选的

我将[0-9] *更改为\ d +,我认为更正确

我改变你的,改为|