web-dev-qa-db-ja.com

GNU sedを使用して正規表現で(および)をエスケープするかどうか

このサイトにいくつかの投稿があり、gnusedでは正規表現で()ではなく\(\)を使用する必要があると書かれています。しかし、 gnu sed manual を調べたところ、\(\)を使用する必要があると指定されていることがわかりました。調子はどう?

21
grok12

ロッカー、ムルガ、クリスに感謝します。あなた方一人一人が私が問題を理解するのを手伝ってくれました。私はここで自分の質問に答えて、(願わくば)ストーリー全体を1か所にまとめます。

使用されているsedには、gnuとbsdの2つのメジャーバージョンがあります。どちらも、基本正規表現の親をグループ化に使用する場合はエスケープする必要がありますが、拡張正規表現で使用する場合はエスケープしない必要があります。 -rオプションはgnuの拡張正規表現を有効にしますが、-Eはbsdの場合は有効にするという点で異なります。

MacOSXの標準sedはbsdです。世界の他の地域の多くはgnusedを標準として使用していると思いますが、誰が何を使用しているかは正確にはわかりません。どちらを使用しているかわからない場合は、次を試してください。

> sed -r

あなたが得る場合

> sed: illegal option -- r

返信すると、bsdがあります。

9
grok12

リンクしたgnusedマニュアルのこの部分 括弧をエスケープする必要があるかどうかは、基本的な正規表現を使用しているか、拡張正規表現を使用しているかによって異なることを説明しています。 この部分-rフラグは、現在のモードを決定します。

編集:grok12のコメントに記載されているように、-E bsdsedのフラグは-rフラグはgnusedで実行されます。

24
murgatroid99

元々sedは、grepや他のすべてのように、グループ化を示すために\(を使用していましたが、(は文字通りのopen-parenと一致していました。

EgrepやPerlを含む多くの新しい正規表現の実装はこれを切り替えたので、\(はリテラルのオープンパレンを意味し、(はグループ化を指定するために使用されました。

したがって、gnusedを使用すると、(特殊文字です。egrepと同じです。しかし、他のシステム(BSDなど)では、私が知る限り、これはまだ古い方法です。残念ながら、これは本当に混乱しています。今ではわかりにくいためです。どちらを使用するか。

15
chrisdowney

エスケープされた括弧(_\(_)は、式の一部としてregexで括弧を検索します。

エスケープされていない括弧(_(_)は、正規表現グループに括弧の内容をまとめます。

つまり、エスケープすると、エンジンはそれらを探しますが、そのままにしておくと、エンジンは結果を変数にグループ化します。 。

実証する例:

$myString = "junk(150)moar";

数字だけを取得するには:
#^\w+\((\d+)\)\w+$#

(_$1_は_150_です)

混乱していることはわかっていますが、grouping括弧と括弧を一致する式の一部として使用していることを示しています。

数年後の更新:

ユーザー @ bmkが正しく指摘している のように、この回答は拡張正規表現には適用されますが、基本的な正規表現には適用されません。ほとんどのプログラミング言語などで、デフォルトの解析エンジンとして基本的な正規表現を見つけることは困難ですが、この回答が状況に当てはまると想定する前に、使用しているエンジンを確認することをお勧めします。

5
rockerest