我有以下形式的字符串新鮮的眼光:需要爲Java正則表達式,是太貪婪
canonical_class_name[key1="value1",key2="value2",key3="value3",...]
的目的是捕捉一組在canonical_class_name然後交替key =值組。目前它與測試字符串不匹配(在以下程序中,testString
)。
必須至少有一個鍵/值對,但可能有很多這樣的對。
問題:目前正則表達式抓住正則類名,正確的第一個鍵,但它吞噬了一切,直到最後一個雙引號,我怎麼讓它抓住鍵值對懶?
這裏是正則表達式,下面的程序放在一起:
(\S+)\[\s*(\S+)\s*=\s*"(.*)"\s*(?:\s*,\s*(\S+)\s*=\s*"(.*)"\s*)*\]
根據你的喜好,你可能會發現程序的版本更容易閱讀。
如果我的節目傳遞的字符串:
org.myobject[key1=\"value1\", key2=\"value2\", key3=\"value3\"]
......這些都是我組得到:
Group1 contains: org.myobject<br/>
Group2 contains: key1<br/>
Group3 contains: value1", key2="value2", key3="value3<br/>
還要說明一點,使用String.split()
我可以簡化表達,但我我將這作爲一種學習體驗,以更好地理解我的正則表達式,所以我不想使用這樣的捷徑。
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class BasicORMParser {
String regex =
"canonicalName\\[ map (?: , map)*\\]"
.replace("canonicalName", "(\\S+)")
.replace("map", "key = \"value\"")
.replace("key", "(\\S+)")
.replace("value", "(.*)")
.replace(" ", "\\s*");
List<String> getGroups(String ormString){
List<String> values = new ArrayList();
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(ormString);
if (matcher.matches() == false){
String msg = String.format("String failed regex validiation. Required: %s , found: %s", regex, ormString);
throw new RuntimeException(msg);
}
if(matcher.groupCount() < 2){
String msg = String.format("Did not find Class and at least one key value.");
throw new RuntimeException(msg);
}
for(int i = 1; i < matcher.groupCount(); i++){
values.add(matcher.group(i));
}
return values;
}
}
這很好。你關於真實問題的直覺和組數都是正確的。還有兩件事......我想避免字符串拆分,但似乎需要以簡單的方式處理逗號分隔的鍵值對列表。它是否正確?之前我在想這些組織會創建匹配集的列表。列表 = MagicRegexObject.match(「(\ S +?\ s)」,stringOfContent);如果還不清楚,我想說,如果有一些神奇的正則表達式對象可以匹配事物並返回匹配對象的列表,那麼我想這樣做... –
Quaternion
有沒有這樣的事情? – Quaternion
你的意思是,像Python的're.findAll()'方法,或PHP的'preg_match_all()'?事實上,每種主要的支持正則表達式的語言都有相同的東西 - 除了Java。 : - /如果這是你正在談論的中間捕捉,那也不會發生。 Java和大多數語言/風格一樣,沒有辦法檢索它們。你只需要重寫正則表達式來匹配鍵/值對,就像我在編輯中一樣。 –