【问题标题】:java regex: match word after another with at least one digitjava正则表达式:一个接一个地匹配至少一个数字的单词
【发布时间】:2016-08-19 05:22:51
【问题描述】:

我有两个字符串:

    String s1 = "The demo 505/rj is bad";   
    String s2 = " demo zero 4";

String val="demo"String g = s1s2,以及正则表达式模式:

Pattern p = Pattern.compile("(?<=" + val +")\\s*\\b(?=\\D*\\d)\\S+\\b");
Matcher m = p.matcher(g);
if (m.find()) {
        String s = g.substring(m.start(), m.end());
        System.out.println(s);
}       

两种可能的情况:

  • 如果 g = s1s = 505/rj - 对我来说意味着该模式可以正常工作
  • 如果g = s2s = zero - 不好 - 因为单词“零”至少不包含一位数字

注意:单词除了字母数字,还可以包含特殊字符

如何修改此模式以解决情况 1 和 2 的问题?

【问题讨论】:

  • 为两者工作是什么意思?您的预期输出是什么?

标签: java regex regex-lookarounds


【解决方案1】:

您需要在您的正则表达式模式中将\D 替换为\S,因为\D 匹配除数字之外的任何字符(因此,它匹配空格!),并且比非空白块检查得更远在当前单词之后。

Pattern p = Pattern.compile("(?<=" + val +")\\s*\\b(?=\\S*\\d)\\S+\\b");
                                                      ^^^^  

this Java demo

您还可以通过matcher.group(0) 获取整个匹配项,无需使用m.start()/m.end()g 获取子字符串。

这里有一个改进:您可以摆脱后视(它们很昂贵)并使用捕获组:

Pattern p = Pattern.compile(val + "\\s*\\b(?=\\S*\\d)(\\S+)\\b");
                            ^^^                      ^^^^^^
//...
String s = m.group(1);

this updated demo

【讨论】:

    【解决方案2】:

    您可以删除lookbehind 和lookahead,使用惰性匹配和捕获组来简化此正则表达式:

    val + "\\s+(\\S*?\\d+\\S*?)\\s+"
    

    【讨论】:

      猜你喜欢
      • 2017-10-01
      • 1970-01-01
      • 2013-05-29
      • 2022-11-24
      • 1970-01-01
      • 2013-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多