4

テキストから cdr (chordpro) へのコンバーターを作成していますが、フォームのコード ラインを検出するのに問題があります。

               Cmaj7    F#m           C7    
Xxx xxxxxx xxx xxxxx xx x xxxxxxxxxxx xxx 

これは私のpythonコードです:

def getChordMatches(line):
    import re
    notes = "[CDEFGAB]";
    accidentals = "(#|##|b|bb)?";
    chords = "(maj|min|m|sus|aug|dim)?";
    additions = "[0-9]?"
    return re.findall(notes + accidentals + chords + additions, line)

リスト ["Cmaj7", "F#m", "C7"] を返したい。上記のコードは機能しません。ドキュメントに苦労しましたが、どこにも行きません。

クラスとグループを連鎖させるだけではうまくいかないのはなぜですか?

編集

ありがとう、私は私のニーズのほとんどをカバーする次のものになりました(たとえば、E#m11とは一致しません)。

def getChordMatches(line):
    import re

    notes = "[ABCDEFG]";
    accidentals = "(?:#|##|b|bb)?";
    chords = "(?:maj|min|m|sus|aug|dim)?"
    additions = "[0-9]?"
    chordFormPattern = notes + accidentals + chords + additions
    fullPattern = chordFormPattern + "(?:/%s)?\s" % (notes + accidentals)
    matches = [x.replace(' ', '').replace('\n', '') for x in re.findall(fullPattern, line)]
    positions = [x.start() for x in re.finditer(fullPattern, line)]

    return matches, positions
4

3 に答える 3

3

(...)に変更して、グループを非キャプチャにする必要があります(?:...)

accidentals = "(?:#|##|b|bb)?";
chords = "(?:maj|min|m|sus|aug|dim)?";

オンラインでの動作を確認してください: ideone


キャプチャ グループがある場合に機能しない理由は、それらのグループのみが返され、一致全体が返されないためです。ドキュメントから:

re.findall(pattern, string, flags=0)

文字列のリストとして、文字列内のパターンの重複しない一致をすべて返します。文字列は左から右にスキャンされ、見つかった順序で一致が返されます。パターンに 1 つ以上のグループが存在する場合は、グループのリストを返します。パターンに複数のグループがある場合、これはタプルのリストになります。空の一致は、別の一致の先頭に触れない限り、結果に含まれます。

于 2012-12-25T13:43:01.977 に答える
3

詳細な正規表現を記述するための特定の構文があります

regex = re.compile(
    r"""[CDEFGAB]                 # Notes
        (?:#|##|b|bb)?            # Accidentals
        (?:maj|min|m|sus|aug|dim) # Chords
        [0-9]?                    # Additions
     """, re.VERBOSE
)
result_list = regex.findall(line)

文字列を一緒に結合するよりも間違いなく少し明確です

于 2012-12-25T13:50:57.047 に答える
2

グループを非キャプチャにする必要があります。

def getChordMatches(line):
    import re
    notes = "[CDEFGAB]";
    accidentals = "(?:#|##|b|bb)?";
    chords = "(?:maj|min|m|sus|aug|dim)?";
    additions = "[0-9]?"
    return re.findall(notes + accidentals + chords + additions, line)

結果:

['Cmaj7', 'F#m', 'C7']
于 2012-12-25T13:45:31.070 に答える