4

これは、これに対するフォローアップの質問です: Regex for matching a music Chord、私に尋ねました。

Stringコードの表現が有効かどうかを知るための正規表現ができたので (前の質問)、コードの 3 つの異なる部分 (ルート ノート臨時記号、コード タイプ) を個別の変数に効果的に取得するにはどうすればよいでしょうか?

単純な文字列操作を行うこともできますが、前のコードに基づいて構築し、そのために正規表現を使用する方が簡単だと思いますか、それとも間違っていますか?

前述の質問から更新されたコードは次のとおりです。

public static void regex(String chord) {                
    String notes = "^[CDEFGAB]";
    String accidentals = "(#|##|b|bb)?";
    String chords = "(maj7|maj|min7|min|sus2)";
    String regex = notes + accidentals + chords; 
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(chord);
    System.out.println("regex is " + regex);
    if (matcher.find()) {
        int i = matcher.start();
        int j = matcher.end();
        System.out.println("i:" + i + " j:" + j);           
    }
    else {
        System.out.println("no match!");
    }
}

ありがとう。

4

3 に答える 3

3

何かを括弧で囲むと (特別な意味を持つ場合を除いて)、キャプチャ グループ(サブパターン) が作成されます。

すでにそのようなサブパターンとしてグループ化さaccidentalsれていますが、それもサブパターンとしてキャプチャするchordsには括弧を追加する必要があります。notes

String notes = "^([CDEFGAB])";
String accidentals = "(#|##|b|bb)?";
String chords = "(maj7|maj|min7|min|sus2)";

慣例により、パターン全体で一致する文字列はグループ 0 であり、すべてのサブパターンはグループ 1、グループ 2 などとしてキャプチャされます。

私は Java の専門家ではありませんが、ドキュメントを読んだ後では、以下を使用してサブパターンの一致にアクセスするように見えます.group()

String note = matcher.group(1);
String acci = matcher.group(2);
String chor = matcher.group(3);

編集:

もともと、String accidentals = "((?:#|##|b|bb)?)";2 番目のサブパターンがオプションであると、一致するものが存在しない場合にグループの番号付けの問題が発生するのではないかと心配していたため、 を提案しました。ただし、少しテストしたところ、そのような非キャプチャ グループでラップしなくても(?: )、グループ 2 は常に存在しますが、一致がない場合は空であることが示唆されています。(いずれにせよ、グループ 2 の空の文字列は、望ましい効果でした。) したがって、 ... = "(#|##|b|bb)?";結局のところ、おそらく十分であると思われます。

于 2012-06-27T15:31:08.757 に答える
2

私は受け入れられた答えが好きですが、ギタープレーヤーとして、G / D、A / D、D / F#などの追加のベースノートが追加されたコードに遭遇します。もちろん、他にも5、6、min6、9、min9、sus4などのコードネームがあります。可能な文字列コードの数を増やしてから、次のコードを追加することを検討してください。あなたが持っている場合、低音の臨時記号:

String chords =
"(maj|maj7|maj9|maj11|maj13|maj9#11|maj13#11|6|add9|maj7b5|maj7#5||min|m7|m9|m11|m13|
m6|madd9|m6add9|mmaj7|mmaj9|m7b5|m7#5|7|9|11|13|7sus4|7b5|7#5|7b9|7#9|7b5b9|7b5#9|
7#5b9|9#5|13#11|13b9|11b9|aug|dim|dim7|sus4|sus2|sus2sus4|-5|)";
String bass = "/([CDEFGAB])";

「ストリングコード」の定義を完了するには、コード辞書を参照することをお勧めします。乾杯!

于 2013-01-17T07:24:50.510 に答える
2

あなたはすでに仕事をしました。最終的な正規表現が次のようになるように、キャプチャグループをもう1つ追加するだけです。

    ^([CDEFGAB])(#|##|b|bb)?(maj7|maj|min7|min|sus2)?$

そして、あなたのノート、偶然、そしてコードは、それぞれ、1回目、2回目、3回目のキャプチャに含まれます。

于 2012-06-27T15:32:20.973 に答える