1

同じ文字列内で以前に定義された変数テンプレートによって識別されるように、正規表現は文字列内に埋め込まれた値を抽出できますか? または、これは Java でより適切に処理されますか?

例: "2012 Ferrari [F12] - Ostrich Leather interior [F12#OL] - Candy Red Metallic [F12#3]" 変数テンプレートは、[F12] などの角括弧で囲まれた最初の文字列であり、必要な変数は次のとおりです。 'OL' や '3' など、そのテンプレートの後続のインスタンス内にあります。

4

1 に答える 1

0

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));
    }
于 2012-07-06T19:33:11.110 に答える