2016-09-26 51 views
0

的可選結束了以下內容:正則表達式匹配給定字符串

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

我想拍攝:

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

什麼Java的正則表達式將允許我這樣做嗎?

我試過(.+)\s\((\d+)\)$,它適用於「約翰史密斯(123)」和「約翰史密斯(123)(456)」,但不適用於「約翰史密斯」。我怎樣才能改變正則表達式爲第一個輸入工作?

+0

你也可以去貪婪'^([^(\ r \ n] +)(?:?:\((*)\))' – revo

+0

@revo在「約翰·史密斯(123)(456)」中,它捕獲了「123」(456),這不是我想要的。 –

+0

是的你是對的:[**'^([^ (\ r \ n] + $ |。*(?:\((。*)\)))**](https://regex101.com/r/hI0eS1/2) – revo

回答

2

您可以打開第一.+懶惰,並與非捕獲可選的組包的後面部分:

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

regex demo

其實,如果你使用的是正則表達式與String#matches()的最後$是多餘的。

詳細

  • (.+?) - 第1組捕獲比斷行符號之外的一個或零個字符,儘可能少(因此,允許隨後的子模式爲「落」到的基團)
  • (?:\s\((\d+)\))? - 一個可選的空白序列,(,第2組捕獲1+數字和一個)
  • $ - 字符串錨定結束。

一個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)); 
    } 
} 
+1

非常感謝! –