0

我需要一个正则表达式,它可以分成这样的表达式:

(6<=5) || (8+1)^2 >= 3 && 4 == 2   

结果应该是这样的列表:

(, 6, <=, 5, ), ||, (, 8, +, 1, ), ^, 2, >=, 3, &&, 4, ==, 2

我做了这个,但它不起作用,它给了我这个结果:

[(, 6, 5, ), (, 8, +, 1, ), ^, 2, 3, 4, 2]

这是正则表达式:

[-]?[0-9]*+([eE][-]?[0-9]+)?|([+-/*///^])|([/(/)])|(>=)|(<=)|(&&)|(==)|(||)

它确实识别数字和算术符号,但它不适用于条件符号(&&、==、||、<=、>=)。

你知道如何纠正吗?

编辑:这是代码:

public void convertToList() {
    String regex = "[-]?[0-9]+([eE][-]?[0-9]+)?|([-+/*\\\\^])|([()])|(>=)|(<=)|(&&)|(==)|([|][|])";
    Matcher m3 = Pattern.compile(regex).matcher(this.stringExp);
    this.arrayExp = new ArrayList<String>(this.stringExp.length());
    while (m3.find()) {
        this.arrayExp.add(m3.group());
    }
}

但即使使用 m.butter 更正的正则表达式它也不起作用(与上述结果相同)

编辑:提供的正则表达式有效,我在输入时犯了一个愚蠢的错误。

4

2 回答 2

2

您的表达中有几个问题:

  • 您没有转义-字符类中的范围运算符[+-/*///^],它可以写为[+\-/*^][-+/*^](如果是第一个/最后一个则无需转义)。
  • 你没有逃脱|in (||),应该是(\|\|)
  • 您的数字表达式与空字符串匹配,您不希望这样。

标记化时的另一个提示:将最长的标记放在表达式中,以防重叠。这是为了获得一个令牌而不是两个令牌<=[<=]

总而言之,您可以使用以下内容:

\d+|[<>=]=|&&|\|\||[-+*/^()]

如果需要,可以用更复杂的数字替换\d+(但不匹配空字符串)。

于 2013-06-11T11:45:18.233 回答
1

您的模式存在一些问题。

  1. 您正在使用|作为替代。因此,您也无法使用|匹配文字管道(正则表达式引擎如何区分?)。因此,您需要转义|应该与字面匹配的内容,或者将其放入字符类中。

  2. 你的逃跑方式是错误的。您需要使用反斜杠\而不是正斜杠/

  3. -在一个字符类中表示一个范围,除非你把它作为第一个或最后一个字符。这在您的[+-...]角色课程中是有问题的。转义连字符或将其移动到类中的第一个或最后一个位置。

  4. 您的第一个选择(数字)允许空匹配,因为一切都是可选的。这会给你一大堆你不想要的额外空结果。去掉*后面的数字。

应用所有这些给出:

[-]?[0-9]+([eE][-]?[0-9]+)?|([-+/*\\^])|([()])|(>=)|(<=)|(&&)|(==)|([|][|])

请注意,您不需要转义(,, and^ inside a character class (unless the^` 是第一个字符)。

另请注意,要将其编写为 Java 字符串,您需要将所有反斜杠加倍:

str = "[-]?[0-9]+([eE][-]?[0-9]+)?|([-+/*\\\\^])|([()])|(>=)|(<=)|(&&)|(==)|([|][|])"

最后,如果你去掉所有不必要的括号,并且使必要的括号不被捕获(我还合并了字符类),你可以对它进行很多优化:

str = "[-]?[0-9]+(?:[eE][-]?[0-9]+)?|[-+/*\\\\^()]|>=|<=|&&|==|[|][|]"

当然,这仅在您想使用捕获来确定每个匹配项是哪种标记时才有效。

工作演示

于 2013-06-11T11:46:18.337 回答