【问题标题】:Java regex pattern&matcherJava 正则表达式模式和匹配器
【发布时间】:2013-12-09 23:56:13
【问题描述】:

我尝试使用 Mathcer 解析此字符串:“2+30*4+(5+6)*7”

使用此模式:“\d*|[()+*-]”

由于某种原因,Matcher 正确地拆分了字符串,但是当遍历拆分后的字符串时,它并没有正确地分割它们,除了数字之外的任何内容都留下了空字符串:

String s = "2+30*4+(5+6)*7";        
    Pattern p = Pattern.compile("\\d*|[()+*-]");
    Matcher m = p.matcher(s);
    while (m.find()) {
          System.out.print("Start index: " + m.start());
          System.out.print(" End index: " + m.end() + " ");
          System.out.println("-----> " + m.group());
    }

这给出了以下输出:

Start index: 0 End index: 1 -----> 2
Start index: 1 End index: 1 -----> 
Start index: 2 End index: 4 -----> 30
Start index: 4 End index: 4 -----> 
Start index: 5 End index: 6 -----> 4
Start index: 6 End index: 6 -----> 
Start index: 7 End index: 7 -----> 
Start index: 8 End index: 9 -----> 5
Start index: 9 End index: 9 -----> 
Start index: 10 End index: 11 -----> 6
Start index: 11 End index: 11 -----> 
Start index: 12 End index: 12 -----> 
Start index: 13 End index: 14 -----> 7
Start index: 14 End index: 14 -----> 

我不明白为什么,例如在第二行中,结束索引是 1(而不是 2)导致一个空字符串: 开始索引:1 结束索引:1 ----->

顺便说一句,当我将模式的顺序更改为 "[()+-]|\d" 时,它可以正常工作...

【问题讨论】:

    标签: java regex matcher


    【解决方案1】:

    \\d* 允许使用空字符串,因为它表示零个或多个数字。如果您不想查找零位(为空)的字符串,请将@​​987654322@ 更改为\\d+

    演示

    String s = "2+30*4+(5+6)*7";        
    Pattern p = Pattern.compile("\\d+|[()+*-]");
    Matcher m = p.matcher(s);
    while (m.find()) {
          System.out.print("Start index: " + m.start());
          System.out.print(" End index: " + m.end() + " ");
          System.out.println("-----> " + m.group());
    }
    

    输出:

    Start index: 0 End index: 1 -----> 2
    Start index: 1 End index: 2 -----> +
    Start index: 2 End index: 4 -----> 30
    Start index: 4 End index: 5 -----> *
    Start index: 5 End index: 6 -----> 4
    Start index: 6 End index: 7 -----> +
    Start index: 7 End index: 8 -----> (
    Start index: 8 End index: 9 -----> 5
    Start index: 9 End index: 10 -----> +
    Start index: 10 End index: 11 -----> 6
    Start index: 11 End index: 12 -----> )
    

    如果你对你的代币位置不感兴趣,你也可以在+-*/()之前或之后split

    String s = "2+30*4+(5+6)*7";
    String[] tokens = s.split("(?<=[+\\-*/()])|(?=[+\\-*/()])");
    for (String token : tokens)
        System.out.println(token);
    

    输出:

    2
    +
    30
    *
    4
    +
    (
    5
    +
    6
    )
    *
    7
    

    【讨论】:

      【解决方案2】:

      \\d* 匹配零个或多个数字。所以在第一次匹配之后,匹配器正在查看"+30*4+(5+6)*7",匹配器首先询问的是,“这个字符串是以零位还是多个数字开头?天哪,是的!” (它首先检查这一点,因为 \\d* 出现在模式中的第一个位置。)这就是匹配器返回空字符串(零位字符串)的原因。

      将其更改为匹配一个或多个数字的\\d+应该可以工作。

      【讨论】:

        【解决方案3】:

        您使用 regix \\d*|[()+*-] 尝试的内容可以表示为

        匹配零个或多个数字。

        您需要使用正则 \\d+|[()+*-] 将其更改为一个或多个,并且可以表示为

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-24
          • 2016-11-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多