正则表达式匹配字符串的可选结尾

时间:2016-09-26 22:08:01

标签: java regex

鉴于以下内容:

"John Smith"
"John Smith (123)"
"John Smith (123) (456)"

我想拍摄:

"John Smith"
"John Smith", "123"
"John Smith (123)", "456"

Java正则表达式允许我这样做?

我已经尝试(.+)\s\((\d+)\)$并且它适用于“John Smith(123)”和“John Smith(123)(456)”但不适用于“John Smith”。如何将正则表达式更改为第一个输入?

1 个答案:

答案 0 :(得分:3)

您可以转换第一个.+懒惰,并使用非捕获可选组包装后一部分:

(.+?)(?:\s\((\d+)\))?$
   ^ ^^^           ^^ 

请参阅regex demo

实际上,如果您使用带有String#matches()的正则表达式,则最后$是多余的。

详细

  • (.+?) - 第1组捕获除了换行符号之外的一个或零个字符,尽可能少(因此,允许随后的子模式到"掉落"进入一个组)
  • (?:\s\((\d+)\))? - 空格的可选序列,(,第2组捕获1位数字和)
  • $ - 字符串锚定结束。

A Java demo

String[] lst = new String[] {"John Smith","John Smith (123)","John Smith (123) (456)"};
Pattern p = Pattern.compile("(.+?)(?:\\s\\((\\d+)\\))?");
for (String s: lst) {
    Matcher m = p.matcher(s);
    if (m.matches()) {
        System.out.println(m.group(1));
        if (m.group(2) != null)
            System.out.println(m.group(2));
    }
}