5

この同様の質問を読み、コードを数回試した後、同じ望ましくない出力が得られ続けます。

検索している文字列が「昨日ウィルマを見た」としましょう。正規表現は、各単語の後に「a」とそれに続くオプションの5 文字またはスペースをキャプチャする必要があります。

私が書いたコードは次のとおりです。

$_ = "I saw wilma yesterday";

if (@m = /(\w+)a(.{5,})?/g){
    print "found " . @m . " matches\n";

    foreach(@m){
        print "\t\"$_\"\n";
    }
}

ただし、次の出力を取得し続けました。

found 2 matches
    "s"
    "w wilma yesterday"

次のものを取得することを期待していましたが:

found 3 matches:
    "saw wil"
    "wilma yest"
    "yesterday"

お気づきのように、内部の戻り値@m$1$2であることがわかるまで。

さて、/gフラグがオンになっているので、問題は正規表現に関するものではないと思いますが、どうすれば目的の出力を得ることができますか?

4

3 に答える 3

3

重複した結果を許可するこのパターンを試すことができます。

(?=\b(\w+a.{1,5}))

また

(?=(?i)\b([a-z]+a.{0,5}))

例:

use strict;
my $str = "I saw wilma yesterday";
my @matches = ($str =~ /(?=\b([a-z]+a.{0,5}))/gi);
print join("\n", @matches),"\n";

より多くの説明:

文字が正規表現エンジンによって「食べられる」と、2度目には食べられないため、正規表現と重複する結果を持つことはできません。この制約を回避する秘訣は、文字列を数回実行できる先読み (照合のみを行うツール) を使用し、内部にキャプチャ グループを配置することです。

この動作の別の例として、単語境界 ( \b) なしでコード例を試して結果を確認できます。

于 2013-07-10T21:12:11.600 に答える