当前位置: 首页 > 知识库问答 >
问题:

在Java中拆分字符串:长度可变的lookahead和lookahead

明阳旭
2023-03-14

我想打破一个字符串Java使用数字作为分隔符,但保留数字。一些研究表明,从String中使用分裂方法()是合适的,但是我不明白如何做到这一点。为了进一步解释我的问题,我将使用一个例子:

Input: 20.55|50|0.5|20|20.55

Required Output: ["20.55","|","50","|","0.5","|","20","|","20.55"]

通过像下面的示例一样调用方法split,而不使用lookahead和lookahead,我得到了预期的输出

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"]    

通过使用lookback,我得到了一个异常

线程“main”java.util.regex.PatternSyntaxException中的异常:Look behind组在索引22(?)附近没有明显的最大长度?

有人能给我解释一下这种行为,并提出解决办法吗?

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"] 

请注意,我必须用**表示指数。

编辑2根据anubhava给出的答案,找到了一个解决方案,可以在所有项目上打破算术表达式

Pattern p = Pattern.compile( "\\*\\*|sin|cos|tan|\\d+(?:\\.\\d+)?|[-()+*/%]" );
Matcher matcher = p.matcher(expression);

while(matcher.find())
    System.out.println(matcher.group());

共有3个答案

曹泉
2023-03-14

尝试:

(?<=\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]

编辑

要使用其他字符作为分隔符以包括 "*", "sin”等。,您可以将正则表达式更改为:

(?<=[0-9a-z*])(?=\|)|(?<=\|)(?=[0-9a-z*])

演示

其中[0-9a-z*]表示数字、字母或"*"。如果您想包含其他字符,只需将其添加到字符类中,如[0-9a-z*E]等。

厍和颂
2023-03-14

问题是,你不能用可变长度定义lookbehinds.*and都匹配可变数量的字符。这是大多数正则表达式引擎的一个限制。

但是,您可以使用可变长度的lookahead。但在您的情况下,这不起作用,因为lookarounds不会使用已经匹配的数据。

你想要的东西可以:

([0-9]+(\\.[0-9]+)?)\\K

\K所做的只是丢弃已经匹配的内容。因此,你仍然会被某些位置拆分,不会用浮动数字重复自己。

许明朗
2023-03-14

您可以使用这个基于环视的正则表达式进行拆分:

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+)?|[-()+*/%]" );

然后,您可以使用Matcher#search()方法来获取所有匹配的令牌。

 类似资料:
  • 问题内容: 如何在Java 中将字符串拆分为相等大小的子字符串。例如。大小相等的4个应该给出输出。 问题答案: 这是regex一线版: 是一个零宽度断言,它与上一个匹配结束的位置匹配。如果是以前没有的比赛,它的输入的开始,同相匹配。后面的封闭式匹配从最后一场比赛的末尾开始算起的四个字符的位置。 都是落后的,都是高级正则表达式功能,并非所有版本都支持。此外,在支持它的所有口味上实现的方式不一致。此技

  • 问题内容: 有没有办法在不知道字符串长度的情况下,将一个字符长的字符串切成4个字符串,每个字符长? 例如: 问题答案:

  • 问题内容: 我有一张表,其中包含一列以可变长度定界的字符串,例如: 20,0,5 ,, ^ 24,0,0 ,, ^ 26,0,0 ,, ^ 281,0,0 ,, ^ 34,0,2 ,, ^ 48,0,2 ,, ^ 44, 0,2 ,, ^ 20,0,10 ,, ^ 20,5,5 ,, ^ 379,1,1 ,, ^ 26,1,2 ,, ^ 32,0,1 ,, ^ 71,0, 2,^ 我需要做的是拆分

  • 问题内容: 使用功能split拆分此String。这是我的代码: 当我尝试这样做时,spli只包含一个字符串。似乎Java在拆分时看不到“ ^”。有人知道如何用字母“ ^”分割此字符串吗? 编辑 解决了:P 问题答案: 这是因为需要一个正则表达式,而不是文字字符串。您必须转义,因为它在regex(字符串开头的锚点)中具有不同的含义。因此,拆分实际上是在第一个字符之前完成的,从而使您完整地返回了完整

  • 我在一个名为string1到String7的程序中有七个字符串。 每个字符串的大小为30个字符。

  • 本文向大家介绍Java中拆分和拼接字符串,包括了Java中拆分和拼接字符串的使用技巧和注意事项,需要的朋友参考一下 要在Java中拆分和连接字符串,请使用以下示例中的split和join方法- 示例 输出结果 一个名为Demo的类包含主函数。这里定义了一个字符串对象,并根据直到最后一个单词的值对其进行分割。循环遍历一个for循环,并根据该值分割字符串。同样,使用join函数连接字符串。相关消息显示