web-dev-qa-db-ja.com

正規表現オプションのキャプチャグループ?

何時間も検索した後、私はこの質問をすることにしました。なぜこの正規表現:^(dog).+?(cat)?は、動作するはずだと思うように動作しません(もしあれば、最初の犬と猫を捕獲します)?ここで何が欠けていますか?

dog, cat
dog, dog, cat
dog, dog, dog
19
forsajt

しぶしぶ修飾された_.+?_の後にオプションのcatを取得しない理由は、それがオプションであり、固定されていないためです。 catを_.+?_シーケンスの「テール」として扱います。

猫を文字列の最後に固定する場合、つまり^(dog).+?(cat)?$を使用すると、一致が得られます:

_Pattern p = Pattern.compile("^(dog).+?(cat)?$");
for (String s : new String[] {"dog, cat", "dog, dog, cat", "dog, dog, dog"}) {
    Matcher m = p.matcher(s);
    if (m.find()) {
        System.out.println(m.group(1)+" "+m.group(2));
    }
}
_

これは( デモ1 )を出力します

_dog cat
dog cat
dog null
_

あなたは猫の後に何かがある場合に対処する方法を知っていますか?

次のように、cat以外のすべてに一致するトリッキーな式を作成することで対処できます。

_^(dog)(?:[^c]|c[^a]|ca[^t])+(cat)?
_

catは、アンカーなしで文字列のどこにでも発生する可能性があります( demo 2 )。

20
dasblinkenlight

@dasblinkenlightの答えは素晴らしいですが、ここで彼/彼女が尋ねられたとき、それの2番目の部分を改善する正規表現があります

あなたは猫の後に何かがある場合に対処する方法を知っていますか?

正規表現^(dog)(.+(cat))?では、グループ番号をキャプチャする必要があります。オプションの猫を取得するために2の代わりに3を使用しますが、char-by-charトリックを使用しなくても同様に機能します。

そして、これが デモ です(これも@dasblinkenlightのデモから分岐したものです。

6
maltalef

@fighaの拡張子は、不要な2番目のキャプチャを行わないように、さらに少し拡張できます。

_?:_を使用して、正規表現のブラケット部分をキャプチャ不可にします。したがって、正規表現は次のようになります:^(dog)(?:.+(cat))?

繰り返しますが、ここに extended demoregex test があります。

3
mft25