3

Unix (\n) 改行を含む複数行の文字列を処理しています。

一部の行は「A、a」(つまり、大文字、カンマ、スペース、小文字) の形式を持っており、文字列からそれらを削除したいと考えています。

正規表現の置換でこれを達成できますが、理解できない謎があります:

"[AZ]" と "[az]" を使用する正規表現は、通常モードと複数行モードの両方で機能します。

"\p{Lu}" と "\p{Ll}" を使用する正規表現は機能しますが、通常モードでのみ機能し、複数行モードでは機能しません。

これらの成功のそれぞれ:

$all =~ s/\n\K *[A-Z], [a-z]\n//g;    # 1

$all =~ s/^ *[A-Z], [a-z]\n//mg;      # 2

$all =~ s/\n\K *\p{Lu}, \p{Ll}\n//g;  # 3

しかし、これは失敗します:

$all =~ s/^ *\p{Lu}, \p{Ll}\n//mg;    # 4

/m スイッチが正規表現の "^" の意味を変更することを期待していましたが、他には何もありませんでした。したがって、ステートメント 4 は、ステートメント 1、2、および 3 と同様に機能すると予想しました。ステートメント 2 は、複数行の構文が問題ないことを示しているようで、ステートメント 3 は、Unicode 文字のプロパティが期待どおりに一致していることを示しているようです。これらを組み合わせると、ステートメント 4 が機能することが期待されます。

Tom Christensen の回答を見てきました。Why does modern Perl avoid UTF-8 by default? 、しかし、複数行の正規表現の一致については何も表示されず、他の場所で答えも見つかりませんでした。

4

1 に答える 1

3

あなたの問題を再現できません。

$ perl -wle'
   $all = "foo\n  A, x\nmeow";
   $all =~ s/^ *[A-Z], [a-z]\n//mg;
   print $all;
'
foo
meow

$ perl -wle'
   $all = "foo\n  A, x\nmeow";
   $all =~ s/^ *\p{Lu}, \p{Ll}\n//mg;
   print $all;
'
foo
meow

Linux で 5.8.8、5.10.1、5.12.4 (スレッド)、および 5.16.0 でテスト済み。

最良の推測:pos($all)ゼロではありません。おそらく、あなたは何か愚かなことをしましたif ($all =~ /.../g)


最初はスペースを削除しても再現できませんでした。

$ perl -wle'
   $all = "foo\nA, x\nmeow";
   $all =~ s/^ *[A-Z], [a-z]\n//mg;
   print $all;
'
foo
meow

$ perl -wle'
   $all = "foo\n  A, x\nmeow";
   $all =~ s/^ *\p{Lu}, \p{Ll}\n//mg;
   print $all;
'
foo
meow

cygwin で 5.10.1 (スレッド化) でテスト済み。

>perl -wle"$all = qq{foo\nA, x\nmeow}; $all =~ s/^ *[A-Z], [a-z]\n//mg; print $all;"
foo
meow

>perl -wle"$all = qq{foo\nA, x\nmeow}; $all =~ s/^ *\p{Lu}, \p{Ll}\n//mg; print $all;"
foo
meow

Windows (ActivePerl) で 5.14.0 (スレッド化) および 5.14.2 (スレッド化) でテスト済み。

しかし、ああ!!!!

>perl -wle"$all = qq{foo\nA, x\nmeow}; $all =~ s/^ *[A-Z], [a-z]\n//mg; print $all;"
foo
meow

>perl -wle"$all = qq{foo\nA, x\nmeow}; $all =~ s/^ *\p{Lu}, \p{Ll}\n//mg; print $all;"
foo
A, x
meow

Windows (ActivePerl) で 5.10.1 (スレッド化)、5.12.1 (スレッド化)、および 5.12.4 (スレッド化) でテスト済み。

古いバージョンの Perl にはバグがあるようです。5.14で修正されたようです。バグはオプティマイザにあるようです ( で示されている-Mre=debugように)。そのため、オプティマイザを「無効化」することで回避できます。

>perl -wle"$all = qq{foo\nA, x\nmeow}; $all =~ s/^ *\p{Lu}, \p{Ll}\n//mg; print $all;"
foo
A, x
meow

>perl -wle"$all = qq{foo\nA, x\nmeow}; $all =~ s/^ *\p{Lu}{1}, \p{Ll}\n//mg; print $all;"
foo
meow
于 2012-08-02T22:11:48.067 に答える