次の形式の文字列があります。
canonical_class_name[key1="value1",key2="value2",key3="value3",...]
目的は、グループ内の canonical_class_name をキャプチャしてから、key=value グループを交互に取得することです。現在、これはテスト文字列と一致しません (次のプログラムでは、testString
)。
少なくとも 1 つのキーと値のペアが必要ですが、そのようなペアは多数存在する場合があります。
質問: 現在、正規表現は標準クラス名と最初のキーを正しく取得しますが、最後の二重引用符まですべてを飲み込んでしまいます。キーと値のペアを遅延取得するにはどうすればよいですか?
次のプログラムがまとめた正規表現は次のとおりです。
(\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/>
もう 1 つ注意してください。I を使用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;
}
}