Jim Davisが指摘したように、文字列の終わり、または文字の前(オプション付き)の両方に一致$
し\n
ます/m
。(perlre Perldocページの「正規表現」セクションを参照してください。修飾子を使用すると、照合を続行できます。g
複数行のPerl正規表現(つまり、行末に1回だけ出現する場合でも、改行文字を含むPerl正規表現)は、ほとんどのPerlプログラマーが処理に問題を抱えるあらゆる種類の複雑さを引き起こします。
一度に1行ずつファイルを読み取る場合は、その行で何かchomp
を行う前に必ず使用してください。これにより、修飾子を使用する際の問題が解決されます。g
Windowsから提供されたLinux/Macでファイルを読み取っている場合は、さらに問題が発生する可能性があります。その場合、\r
と\n
文字の両方があります。プログラムをデバッグしようとして最近わかったように、\r
文字はによって削除されませんchomp
。私は今、常にテキストファイルを開いて読むようにしています
このような:
open my $file_handle, "<:crlf", $file...
これは、これが実際にLinux / Macシステム上のWindowsファイルである場合にのみ、\r\n
文字を自動的に置き換えます。\n
これが通常のLinux/Macテキストファイルの場合、何もしません。他の明白な解決策は、Windowsを使用しないことです(リムショット!)。
もちろん、あなたの場合、最初にchompを使用すると、次のようになります。
$cat file
line one
line two
line three
line four
$ perl -pe 'chomp;s/$/addthis::/g`
line oneaddthis::line twoaddthis::line threeaddthis::line fouraddthis::
チョップがを削除した\n
ので、行が印刷されたときに表示されなくなりました。うーん...
$ perl -pe 'chomp;s/$/addthis/g;print "\n";
line oneaddthis
line twoaddthis
line threeaddthis
line fouraddthis
それはうまくいきます!そして、あなたのワンライナーはほんの少し理解できないだけです。
もう1つは、DamianConwayが著書PerlBestPracticesの第12章で推奨しているより現代的なアプローチを取ることです。
\A
および\z
を文字列境界アンカーとして使用します。
常に/mを使用するという以前の方法を採用していなくても、デフォルトの意味で^と$を使用することはお勧めできません。確かに、Perl正規表現1で^と$が実際に何を意味するかはご存知でしょう。しかし、あなたのコードを読んだり維持したりする人は知っていますか?それとも、前述の方法でそれらのメタ文字を誤解する可能性が高いですか?Perlは、常に「文字列の開始」と「文字列の終了」を意味するマーカーを提供します:\Aと\z(大文字のA、ただし小文字のz)。/ mがアクティブであるかどうかに関係なく、「文字列の開始/終了」を意味します。読者が^と$の意味に関係なく、「文字列の開始/終了」を意味します。
Conawayのアドバイスに従い、これを行った場合:
perl -pe 's/\z/addthis/mg' myfile.txt
addthis
フレーズがすべての行の最後にのみ追加されていることがわかります。
$cat file
line one
line two
line three
line four
$ perl -pe `s/\z/addthis/mg` myfile.txt
line one
addthisline two
addthisline three
addthisline four
addthis
それがどれほどうまく機能するかを見てください。それaddthis
が各行の最後に追加されました!\n
...その行の文字の直後。
十分に楽しんで、仕事に戻ります。(待ってください、それは大統領の日です。それは有給休暇です。もちろん、火曜日の朝までに私が約束したすべてのことを除いて、今日は仕事はありません)。
これが、正規表現がどれほど楽しいか、そしてなぜ多くの人がPythonを学ぶことにしたのかを理解するのに役立つことを願っています。
1. Perlで何を意味し^
、実際に意味するのかを知っていますか?$
ええと、もちろんそうです。私は数十年の間Perlでプログラミングしてきました。うん、私はこれらすべてのものを知っています。(自己メモ:$
どうやら私がいつも思っていた意味ではありません。)