web-dev-qa-db-ja.com

pcregrep改行アサーションバグの背後にあるもの?

pcregrepを使用して、空白行の後の最初の行を印刷しようとしています。たとえば、ファイルの内容

first line

second line

印刷するにはsecond lineが必要です。全体を通して同じ正規表現を使用したいくつかのテストがあります

Python 2.7

python -c "import re; print re.search(r'(?<=\n\n).*?$',\
    open('file').read(), re.MULTILINE).group()"
second line

GNU grep 2.16

grep -oPz  '(?<=\n\n).*?$' file
second line

Pcregrepバージョン8.12を使用

pcregrep -Mo  '(?<=\n\n).*?$' file
(no output)

いくつかのテストに基づくと、pcregrepは一般に後読みアサーションをサポートしていますが、特に後読みアサーション内では\nを処理できないようです。先読みアサーション内の\nは問題ありません。

RHELとUbuntuでテスト済み。何か案は?

3
iruvar

どうやらあなたはそれが探したい改行のタイプをpcregrepに指定することができます。 -Nスイッチは、PCREモードを使用するときにこれを行います。

-N newline-type、-newline = newline-type PCREライブラリは、行の終わりを示すための5つの異なる規則をサポートしています。これらは、1文字のシーケンスCR(キャリッジリターン)とLF(改行))、2文字のシーケンスCRLF、前述の3つのタイプのいずれかを認識する「anycrlf」規則、およびUnicode行終了シーケンスが行を終了すると想定される「任意の」規則。Unicodeシーケンスは、上記の3つに加えて、VT(垂直タブ、U + 000B)、FF(フォームフィード、U + 000C)、 NEL(次の行、U + 0085)、LS(行区切り文字、U + 2028)、およびPS(段落区切り文字、U + 2029)。

PCREライブラリが構築されると、デフォルトの行末シーケンスが指定されます。これは通常、オペレーティングシステムの標準シーケンスです。このオプションで特に指定されていない限り、pcregrepはライブラリのデフォルトを使用します。このオプションに指定できる値は、CR、LF、CRLF、ANYCRLF、またはANYです。これにより、pcregrepを使用して、行末を変更することなく、他の環境からのファイルをスキャンできます。スキャンされているデータがこのオプションで設定された規則と一致しない場合、pcregrepは奇妙な方法で動作する可能性があります。このオプションは、オペレーティングシステムの標準の改行シーケンスを使用することが期待される-f、-exclude-from、または--include-fromオプションで指定されたファイルには適用されないことに注意してください。

$ pcregrep -Mo  -N CRLF '(?<=\n\n).*?$' sample.txt 
second line

$

その他の奇妙な行動

興味深いことに、後読みから先読みに変更すると、次のような結果が得られます。

$ pcregrep -Mo  '(?>\n\n).*?$' sample.txt 


second line
$
3
slm