4

正規表現を使用して単語を のグループに分割(vowels, not_vowels, more_vowels)し、マーカーを使用してすべての単語が母音で始まり母音で終わるようにしたいと考えています。

import re

MARKER = "~"
VOWELS = {"a", "e", "i", "o", "u", MARKER}

word = "dog"

if word[0] not in VOWELS:
    word = MARKER+word

if word[-1] not in VOWELS:
    word += MARKER

re.findall("([%]+)([^%]+)([%]+)".replace("%", "".join(VOWELS)), word)

この例では、次のようになります。

[('~', 'd', 'o')]

問題は、一致が重複することを望んでいることです-母音の最後のセットが次の一致の最初のセットになる必要があります。これは、正規表現を次のように置き換えると、先読みで可能になるようです。

re.findall("([%]+)([^%]+)(?=[%]+)".replace("%", "".join(VOWELS)), word)

我々が得る:

[('~', 'd'), ('o', 'g')]

つまり、私たちは私が望むものと一致しています。ただし、母音の最後のセットは返されません。私が望む出力は次のとおりです。

[('~', 'd', 'o'), ('o', 'g', '~')]

これは可能だと思います(正規表現が母音の2番目のセットをチェックできる場合、それらを返すことができない理由はわかりません)が、ブルートフォースメソッドを超えてループする方法が見つかりませんそれらを取得し、次の一致の最初の文字を最後の一致に追加し、文字列の最後の文字を最後の一致に追加した後の結果。これを行うためのより良い方法はありますか?

機能する2つのことは、値をキャプチャしながら、先読み値をキャプチャするか、一致するテキストを消費しないことです-どちらの方法も見つかりません。

4

2 に答える 2

10

投稿した直後に見つけました:

re.findall("([%]+)([^%]+)(?=([%]+))".replace("%", "".join(VOWELS)), word)

先読み内にブラケットのペアを追加することは、それ自体がキャプチャになることを意味します。

私はこれがかなりあいまいで見つけにくいと感じました - 他の誰もがこれを明白だと思ったのかどうかはわかりませんが、私の立場にある他の誰かが将来これをより簡単に見つけられることを願っています.

于 2012-04-09T23:26:33.713 に答える
3

正規表現エンジンにこれを行わせようとはしません。文字列を子音と母音のチャンクに分割し、重複する結果を生成します。''このように、単語が実際には母音ではない、または母音で終わらない場合、「母音」部分として問題ないと仮定して、実際にマーカーをハックする必要もありません。

def overlapping_matches(word):
    pieces = re.split('([^aeiou]+)', word)
    # There are other ways to do this; I'm kinda showing off
    return zip(pieces[:-2], pieces[1:-1], pieces[2:])[::2]

overlapping_matches('dog') # [('', 'd', 'o'), ('o', 'g', '')]

word(母音のみが含まれている場合、これはまだ失敗しますが、必要に応じて簡単に修正されます。)

于 2012-04-10T00:28:50.857 に答える