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


24

私は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正規表現を有効にできますか?方法はありますか?

回答:


11

さまざまなツールとそのバージョンが、正規表現のさまざまなバリエーションをサポートしています。それぞれのドキュメントは、それらがサポートするものを教えてくれます。

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

たとえば、POSIXで指定されている基本的な正規表現のすべての最新の実装sedおよびgrep実装(少なくとも1つのバージョンまたは標準のもう1つのバージョンですが、この標準は過去数十年でそれほど進化していません)。

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

そう:

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

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

[\w]POSIXでは、バックスラッシュまたはw。そのため、利用可能な場所grepsed実装は見つかりません(非標準オプションを使用しない限り)。

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

GNU grepは独自の正規表現エンジンを使用していましたが、現在はGNU libcのエンジンを使用しています(ただし、独自のコピーを埋め込みます)。

これは、ロケールのalnumsと下線に一致することを意図しています。ただし、現在のところ、1バイト文字のみに一致するというバグがあります(たとえば、UTF-8ロケールでは、明らかに文字であるにもかかわらず、éが単一であるすべてのロケールでéに一致しますが、éではありません)キャラクター)。

\wperl regexpおよびPCREにも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:]]


[_[:alnum:]][\w/][_[:alnum:]/]その場合)のように拡張できる素晴らしい回避策です。
ビール

1
この回答は、GNUの制限に関しては時代遅れになっていますgrep
ステファンシャゼラス

7

あなたは正しい\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

perlreより多くのPCREスタッフを参照してください。

perlはここから入手できます:http : //www.activestate.com/activeperl/downloads


\w[\w]私の質問の違いに注意してください。各コマンドの出力で更新し、どのコマンドが機能していてどれが機能していないかを明確にします。特に、sed理解\wしますが、理解しません[\w]。また、たとえば[\w]使用[\w/]したいので、仕事をする必要があります。
ビール

その場合、それはおそらく引用の問題です。いずれにせよ- perlそれを行うことができます:)。
-Sobrique

ありがとう!StéphaneChazelasの答えは、私が求めたものに少し近い(perlがインストールされていないため-du * b Windowsユーザーだと思う)ので、彼の答えを受け入れました。
ビール

大丈夫-しかし、WindowsにPerlをインストールすることをお勧めします。それは私の最初の事の一つであり、私はそれが非常に役立つと思います。
-Sobrique

\wperlになる前はGNU grep(80年代)で、おそらくそれ以前でもGNU emacsでした。
ステファンシャゼル

1

私はそれを疑うgrepし、sed適用する際に、異なる決定され[]、いつ拡大することを\w。perlでは、正規表現\wは任意の単語文字を意味し[]、グループを定義して、その中の任意の文字を一致として適用します。\w前に「展開」[]すると、すべての単語文字の文字クラスになります。代わりに、あなたがない場合は[]最初の次の2つの文字で文字クラスを持つことになります\し、wそれは、これら2つの文字の一つ以上を含む任意のパターンにマッチします。

そのため、特殊なシーケンスas およびdo を尊重するのではなく、一致する正確な文字を含むものとして、それを処理しsedているように見えます。もちろん、この例では完全に不要ですが、それが重要になる場合を想像することができますが、それから括弧とorsで動作させることができます。[]\wperlgrep[]


そうだとしたら驚かれるでしょう。\ はエスケープコードであり、区切り文字のエスケープに使用します。本質的に、それは他のものよりも高い優先度を持たなければならないことを意味します。\w正規表現の仕様の一部ではないため、実装されていない可能性が高いと思う
-Sobrique

まあ、経験的に私のためのsedヌーを用いた場合のようだ:echo whe\\ere | sed -r 's/[\w]+/gone/g私を与えるgonehegoneereことは、各マッチングされているかのよう` and w`をして置換を行う
エリックRenouf

Eric Renoufが見ているものを確認できます。それで、どうにかバックスラッシュをエスケープしたいですか?:)
ビール

私はそれが正しい答えだとは思わない。ちょうどあなたが別のツールを選択する文字クラスの両方のタイプを使用する必要がある場合の答えがあるので、文字クラス定義の異なるタイプの混在をサポートし、またはあなたがしているピッキングは、それがサポートしている構文を使用sedの場合はありませんsedの
エリックRenouf
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.