我想使用数字作为分隔符来破坏Java中的String,但保留数字。一些研究表明,使用String中的split method()是合适的,但我不明白该怎么做。为了进一步解释我的问题,我将使用一个例子:
Input: 20.55|50|0.5|20|20.55
Required Output: ["20.55","|","50","|","0.5","|","20","|","20.55"]
通过调用方法拆分,就像我在下面给出的示例一样,没有lookahead和lookbehind,我得到了我期待的输出
expression.split("([0-9]+(\\.[0-9]+)?)")
Output: ["|","|","|","|"]
但如果我试着用前瞻来做这件事:
expression.split("(?=([0-9]+(\\.[0-9]+)?))")
Output: ["2","0.","5","5|","5","0|","0.","5|","2","0|","2","0.","5","5"]
通过使用lookbehind我得到一个例外:
线程“main”中的异常java.util.regex.PatternSyntaxException: Look-behind组在索引附近没有明显的最大长度 22(?< =([0-9] +(。[0-9] +)?))
任何人都可以向我解释这种行为,并建议一个解决方案吗?
PS:我知道我可以使用'|'打破字符串,但这只是一个愚蠢的例子,我实际上需要一个更复杂的正则表达式...修改
由于分隔符的长度,似乎无法做我想要的事情。由于我正在寻找一个解决较小问题的解决方案,然后我可以将其用于剩下的练习,我将重新说明是否有转变,就像在第二和第三个答案中找到的那样:
我想打破包含算术表达式的Java中的String,并保留其所有项目。例如:
Input: 20.55 * 0.5 ** cos(360) + sin 0 * cos 90 + 1 * sin (180 + 90) * 0
Output: ["20.55", "*", "0.5", "**", "cos", "(", "360", ")", "+", "sin", "0", "*", "cos", "90", "+", "1", "*", "sin", "(", "180", "+", "90", ")", "*", "0"]
PSS:请注意我必须使用'**'进行取幂。
编辑2 根据anubhava给出的答案,发现一个解决方案打破了所有项目的算术表达式
Pattern p = Pattern.compile( "\\*\\*|sin|cos|tan|\\d+(?:\\.\\d+)?|[-()+*/%]" );
Matcher matcher = p.matcher(expression);
while(matcher.find())
System.out.println(matcher.group());
答案 0 :(得分:2)
您可以使用此基于外观的正则表达式进行拆分:
String[] toks = "20.55|50|0.5|20|20.55".split( "(?=[^\\d.])|(?<=[^\\d.])" );
for (String tok: toks)
System.out.printf("%s%n", tok);
<强>更新
您可以将此正则表达式用于匹配您的令牌:
Pattern p = Pattern.compile( "sin|cos|tan|\\d+(?:\\.\d+)?|[-()+*/%]" );
然后,您可以在while循环中使用Matcher#find()
方法来获取所有匹配的令牌。
答案 1 :(得分:1)
问题在于您无法定义具有可变长度的外观。 +
,*
和?
都匹配可变数量的字符。这是大多数正则表达式引擎的限制。
但是,您可以使用可变长度的前瞻。但在你的情况下,这不会起作用,因为外观不会消耗已经匹配的数据。
你想要的东西:
([0-9]+(\\.[0-9]+)?)\\K
\K
所做的只是抛弃已经匹配的内容。因此,您仍将按某些位置进行拆分,并且不会使用浮动数字重复自己。
答案 2 :(得分:1)
尝试:
(?<=\d)(?=\|)|(?<=\|)(?=\d)
在Java中:
public class RegexTest{
public static void main(String[] args){
String string = "20.55|50|0.5|20|20.55";
System.out.println(Arrays.toString(string.split("(?<=\\d)(?=\\|)|(?<=\\|)(?=\\d)")));
}
}
结果:
[20.55,|,50,|,0.5,|,20,|,20.55]
修改
使用其他字符作为分隔符来包含&#34; *&#34;,&#34; sin&#34;等等,您可以将正则表达式更改为:
(?<=[0-9a-z*])(?=\|)|(?<=\|)(?=[0-9a-z*])
其中[0-9a-z*]
表示数字,字母或&#34; *&#34;。如果要包含其他字符,只需将其添加到字符类,如[0-9a-z*E]
等。