我需要一个正则表达式,可以将一个表达式分成这样的表达式:
(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]+)?|([+-/*///^])|([/(/)])|(>=)|(<=)|(&&)|(==)|(||)
它确实识别数字和算术符号,但它不适用于条件的符号(&amp;&amp;,==,||,&lt; =,&gt; =)。
你知道怎么纠正吗?
编辑:这是代码:
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修正的正则表达式也不起作用(与上面的结果相同)
编辑:正则表达式提供了作品,我输入了一个愚蠢的错误。
答案 0 :(得分:2)
你的表达中有几个问题:
-
中的范围运算符[+-/*///^]
,它可以写为[+\-/*^]
或[-+/*^]
(如果没有,则无需转义第一/最后一个)。|
中的(||)
,应(\|\|)
标记化时的提示:如果重叠,请将最长的标记放在表达式中。这是<=
在[<=]
之前获得一个令牌而不是两个令牌。
总而言之,您可以使用以下内容:
\d+|[<>=]=|&&|\|\||[-+*/^()]
如果您愿意(但不要匹配空字符串),请将\d+
替换为数字更复杂的内容。
答案 1 :(得分:1)
您的模式存在一些问题。
您正在使用|
作为替代。因此,您不可能使用|
来匹配文字管道(正则表达式引擎如何区分?)。因此,您需要转义应该按字面意思匹配的|
,或者将其放在字符类中。
你的逃跑是错误的。您需要使用反斜杠\
而不是正斜杠/
。
-
表示范围,除非您将其作为第一个或最后一个字符。这在您的[+-...]
字符类中存在问题。要么逃避连字符,要么将其移到课堂的第一个或最后一个位置。
您的第一个替代(数字)允许空匹配,因为一切都是可选的。这将为您提供一大堆您不想要的额外空结果。删除号码后的*
。
应用所有这些:
[-]?[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]+)?|[-+/*\\\\^()]|>=|<=|&&|==|[|][|]"
当然,除非您想使用捕获来确定每个匹配的标记类型,否则这只能起作用。