[英]Java regex matching greedy data apart from optional suffix
給定一個像
Prefix without commas, remainder with optional suffix (optional suffix)
一次匹配並提取字符串的3部分的最佳Java正則表達式是什么?
對於上面的示例,這3個組(用引號引起來)將是
字符串的所有3個部分的長度都是可變的。 “剩余”部分本身可以包含逗號和括號,並且可選的后綴可以以空格開頭,也可以不以空格開頭,然后是左括號,后面是零個或多個字符,然后是右括號,后面是可選空格,然后是行結束。
嘗試類似的東西
([^,]*),(.*)(\s*\(.*\))?
僅產生組1和2,將組3置於組2的末尾。
([^,]*),(.*)(\\s*\\(.*\\))?
失敗的原因是,正則表達式已經以([^,]*),(.*)
,並且不需要檢查(回溯)其余的。
要使其正常工作,請按如下所示更改它(可能有多個選項),這些匹配要么不帶最后一個括號,要么將匹配最后一個括號:
^([^,]*),(.*[^\) ]\s*$) | ([^,]*),(.*)(\s*\(.*\))\s*$
結果( $1 + $3
和$2 + $4
應該合並,如果沒有可選前綴,則填充$1
和$2
):
3: Prefix without commas
4: remainder with optional suffix
5: (optional suffix)
在這里,我假設您的可選后綴可以出現多次。 閱讀問題的另一種方式是,您希望重復中間部分,即$3
包含在$2
。 您可以按照以下步驟進行操作:
^([^,]*),(.*(?:[^\) ]\s*$ | (\s*\(.*\)\s*$)))
結果:
1: Prefix without commas
2: remainder with optional suffix (optional suffix)
3: (optional suffix)
編輯:在正則表達式上方進行了更新,以使右括號后可以留有空格(這很細微,您需要在負字符類中添加空格),並錨定了正則表達式以加快速度並減少回溯
您可以使用以下正則表達式:
"^([^,]*),([^()]*)(\\s*\\(.*\\))?$"
正則表達式匹配:
^
-字符串的開頭 ([^,]*)
-(第1組)0個或多個字符,
,
-文字,
([^()]*)
-(第2組)除(
和)
以外的0個或更多字符 (\\\\s*\\\\(.*\\\\))?
-(第3組)可選組(由於?
量詞表示前面的子模式出現1或0):
\\\\s*
-0或多個空格 \\\\(.*\\\\)
-文字(
然后是除換行符以外的盡可能多的字符,直到最后一個)
。 $
-字符串的結尾(如果實際字符串可以更長,則刪除該字符串,而您正在尋找較小的子字符串)。 String str = "String prefix without commas, variable length remainder with optional suffix (optional suffix)";
Pattern ptrn = Pattern.compile("^([^,]*),([^()]*)(\\s*\\(.*\\))?$");
Matcher matcher = ptrn.matcher(str);
while (matcher.find()) {
System.out.println("First group: " + matcher.group(1)
+ "\nSecond group: " + matcher.group(1)
+ (matcher.group(3) != null ?
"\nThrid group: " + matcher.group(3) : ""));
以下正則表達式:
^([^,]*),(.*?)(?:\(([^()]*)\))?\s*$
在組2中使用惰性量詞以確保組3將匹配(如果有任何括號)。 另一方面,組3不允許嵌套的括號,僅在字符串的最后一組括號中強制匹配。
碼:
String text = "String prefix without commas, variable length ())(remainde()r with )optional (suffix (optional suffix)";
Pattern regex = Pattern.compile("^([^,]*),(.*?)(?:[(]([^()]*)[)])?\\s*$");
Matcher m = regex.matcher(text);
if (m.find()) {
System.out.println("1: " + m.group(1));
System.out.println("2: " + m.group(2));
System.out.println("3: " + m.group(3));
}
輸出:
1: String prefix without commas
2: variable length ())(remainde()r with )optional (suffix
3: optional suffix
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.