Javaについて言及しているので、Javaの実装であるPatternを使用していると仮定します。
Javaのパターンは、いわゆるバックリファレンスをサポートしています。これは、以前のキャプチャグループが一致したのと同じ値を一致させるために使用できます。
残念ながら、単一のキャプチャグループから複数の値を抽出することはできないため、単一のパターンでこれを行う場合は、一致させるテンプレートの数をハードコーディングする必要があります。
1つの変数の場合、次のようになります。
\[(.*?)\].*?\[\1#(.*?)\]
^^^^^ ^^^^^ variable
template ^^ back reference to whatever template matched
次のように、オプションの非キャプチャグループにラップすることで、オプションの一致をさらに追加できます。
\[(.*?)\].*?\[\1#(.*?)\](?:.*?\[\1#(.*?)\])?(?:.*?\[\1#(.*?)\])?
^ optional group ^ another one
これは、最大3つの変数に一致します。
String s = "2012 Ferrari [F12] - Ostrich Leather interior [F12#OL] - Candy Red Metallic [F12#3]";
String pattern = "\\[(.*?)\\].*?\\[\\1#(.*?)\\](?:.*?\\[\\1#(.*?)\\])?(?:.*?\\[\\1#(.*?)\\])?";
Matcher matcher = Pattern.compile(pattern).matcher(s);
if (matcher.find()) {
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println(matcher.group(i));
}
}
// prints F12, OL, 3, null
ただし、任意の数の変数を一致させる必要がある場合は、最初のパスでテンプレートを抽出してから、2番目のパターンでテンプレートを埋め込むことに頼る必要があります。
// compile once and store in a static variable
Pattern templatePattern = Pattern.compile("\\[(.*?)\\]");
String s = "2012 Ferrari [F12] - Ostrich Leather interior [F12#OL] - Candy Red Metallic [F12#3]";
Matcher templateMatcher = templatePattern.matcher(s);
if (!templateMatcher.find()) {
return;
}
String template = templateMatcher.group(1);
Pattern variablePattern = Pattern.compile("\\[" + Pattern.quote(template) + "#(.*?)\\]");
Matcher variableMatcher = variablePattern.matcher(s);
while (variableMatcher.find()) {
System.out.println(variableMatcher.group(1));
}