web-dev-qa-db-ja.com

sedの正規表現で[\ w] +を使用するには?

私はWindowsを使用していますが、私の質問はここに正しく配置されていると思います。

C:\Users\User>grep --version
GNU grep 2.6.3

C:\Users\User>sed --version
GNU sed version 4.2.1

次の作品(hereの出力)に気づきました。

echo here | grep -E "\w+"
echo here | grep -E "[her]+"

しかし、これは機能しません(何も出力しません):

echo here | grep -E "[\w]+"

これも(hereを出力して)行います:

echo here | grep -P "[\w]+"

そう [\w]は、Perl正規表現に固有の何かだと思います。あれは正しいですか?

では、sedについて話しましょう。これは動作します(goneを出力):

echo here | sed -r "s/\w+/gone/"
echo here | sed -r "s/[her]+/gone/"

そして再び、これはしません(hereを出力します):

echo here | sed -r "s/[\w]+/gone/"

では、sedのPerl正規表現をアクティブにするにはどうすればよいですか?

26
bers

さまざまなツールとそのバージョンは、正規表現のさまざまなバリアントをサポートしています。それぞれのドキュメントには、それらのサポート内容が記載されています。

標準が存在するため、準拠するすべてのアプリケーションで使用できる最小限の機能セットに依存できます。

たとえば、sedgrepの最新の実装はすべて、POSIXで指定された基本正規表現を実装します(少なくとも1つのバージョンまたは他のバージョンの標準ですが、その標準はそれほど進化していません。過去数十年で考慮してください)。

POSIX BREおよびEREでは、[:alnum:]文字クラスがあります。これは、ロケールの文字と数字に一致します(ロケールがCでない限り、a-zA-Z0-9より多くのものが含まれていることに注意してください)。

そう:

grep -x '[[:alnum:]_]\{1,\}'

1つ以上のalnumまたは_と一致します。

[\w]は、POSIXでバックスラッシュまたはwと一致するために必要です。そのため、それが利用可能なgrepまたはsed実装は見つかりません(非標準オプションを使用しない限り)。

\wのみの動作はPOSIXでは指定されていないため、実装は必要なことを実行できます。 GNU grepがずっと前に追加した。

GNU grepには以前は独自の正規表現エンジンがありましたが、現在はGNU libcのものを使用しています(独自のコピーを埋め込んでいます)。

これは、ロケールのアルナムとアンダースコアに一致させることを目的としています。ただし、現在のところ、シングルバイト文字のみに一致するというバグがあります(たとえば、UTF-8ロケールでは、それが明らかに文字であり、éが単一のすべてのロケールでéに一致する場合でも、キャラクター)。

また、Perl regexpとPCREには\w regexp演算子があります。 PCRE/PerlはPOSIX正規表現ではありません。これらは完全に別のことです。

GNU grep -PはPCREを使用するため、-Pを使用しない場合と同じ問題が発生します。ただし、(*UCP)を使用することで回避できます(ただし、UTF8以外にも副作用があります)ロケール)。

GNU sedもGNU libcの正規表現に独自の正規表現を使用します。GNU grep

GNU sedはPCREをサポートしていません。コードには以前に試みられたいくつかの証拠がありますが、それはもはや議題に含まれていないようです。

Perlの正規表現が必要な場合は、Perlを使用してください。

それ以外の場合は、sed/grepの特定の実装の偽の非標準機能に依存するのではなく、標準に固執し、[_[:alnum:]]を使用する方が良いと思います。

11

あなたは正しいです - \wはPCRE-Perl互換の正規表現の一部です。ただし、これは「標準」の正規表現の一部ではありません。 http://www.regular-expressions.info/posix.html

sedの一部のバージョンはそれをサポートしている可能性がありますが、Perlモードでsedを使用して-p 国旗。 (一緒に -e)。 (詳細は perlrun にあります)

しかし、あなたは[]その例ではそれを囲んでいます-それは有効なもののグループのためのものです。

echo here  | Perl -pe 's/\w+/gone/'

またはWindowsの場合:

C:\>echo here  | Perl -pe "s/\w+/gone/"
gone
C:\>echo here  | Perl -pe "s/[\w\/]+/gone/"
gone

PCREの詳細については perlre を参照してください。

ここでPerlを入手できます: http://www.activestate.com/activeperl/downloads

7
Sobrique

grepsedは、[]をいつ適用するか、および\wをいつ展開するかによって決定が異なると思います。 Perlの正規表現では、\wは任意のWord文字を意味し、[]はグループを定義して、一致する文字を適用します。 \wの前に[]を「展開」すると、すべてのWord文字の文字クラスになります。代わりに最初に[]を実行すると、2つの文字\wの文字クラスが作成され、これらの2つの文字の1つ以上を含むすべてのパターンに一致します。

したがって、sed[]を認識しており、特殊なシーケンス\wPerlgrep do。もちろん、この例では[]は完全に不要ですが、それが重要であるケースを想像できるかもしれませんが、それを括弧やORで動作させることもできます。

1
Eric Renouf