例えばそうです
cat sed_data.txt | sed 's/\b[0-9]\{3\}\b/NUMBER/g'
、私がすることをしなければならない正規表現を形成するために、文字をエスケープします。この場合、何度も解釈されるために中括弧をエスケープする必要がありました。
どうして?エスケープされない限り、すべてが正規表現文字になると期待していました。すなわち反対です。
s/regex//g
すでに正規表現を想定しており、必要なテキストであると予想しますエスケープされる
例えばそうです
cat sed_data.txt | sed 's/\b[0-9]\{3\}\b/NUMBER/g'
、私がすることをしなければならない正規表現を形成するために、文字をエスケープします。この場合、何度も解釈されるために中括弧をエスケープする必要がありました。
どうして?エスケープされない限り、すべてが正規表現文字になると期待していました。すなわち反対です。
s/regex//g
すでに正規表現を想定しており、必要なテキストであると予想しますエスケープされる
回答:
これは、おそらくPerlや友人が使用していたERE(拡張正規表現)ではなくsed
、POSIX BRE(基本正規表現)を使用するためです。
sed(1)
manページから:
REGULAR EXPRESSIONS
POSIX.2 BREs should be supported, but they aren't completely because of
performance problems. The \n sequence in a regular expression matches
the newline character, and similarly for \a, \t, and other sequences.
上記のリンクからの関連する引用:
基本正規表現またはBREフレーバーは、従来のUNIX grepコマンドで使用されるフレーバーと同様のフレーバーを標準化します。これは、現在も使用されているかなり古い正規表現フレーバーです。このフレーバーを際立たせることの1つは、ほとんどのメタキャラクターがメタキャラクターにフレーバーを与えるためにバックスラッシュを必要とすることです。POSIX EREを含む他のほとんどのフレーバーは、バックスラッシュを使用してメタ文字の意味を抑制します。
クレイグ・サンダースのコメントから逐語的に引用:
GNU sedでは少なくとも、sedに-rまたは--regexp-extendedコマンドラインオプションを指定して拡張正規表現を使用するように指示できます。これは、sedスクリプトが過度にエスケープされて醜くなりたくない場合に便利です。
-r
か、--regexp-extended
コマンドラインオプション。これは、sedスクリプトが過度にエスケープされて醜くなりたくない場合に便利です。
sed
実装(それらがEREをサポートする場合、主にBSD)は-E
、代わりにそれを使用する傾向があります(これはと同じオプションであるため、はるかに理にかなっていますgrep
。なぜGNU sed
が-r
私にとって謎なのかを選択した理由です)。
それは歴史的な理由によるものです。
Regexpはed
、70年代初頭にユーティリティでUnixに最初に導入されました。しかしがed
に基づいていたqed
、実装が同じ著者によって、より複雑な正規表現を理解し、ed
唯一の理解^
、$
、[...]
、.
、*
および\
上記のすべてをエスケープします。
さて、より多くの演算子を持つ必要が生じたとき、後方互換性を壊すことなくそれらを導入する方法を見つけなければなりませんでした。スクリプトを使用するために使用した場合s
ed
のようにコマンドをs/foo() {/foo (var) {/g
すべてのインスタンス置き換えることfoo() {
としfoo(var) {
、あなたが導入された(
か{
をオペレータに、それはそのスクリプトを破ります。
ただし、それはRE演算子ではなかったs/foo\(\) {/foo\(var\) {/
ので同じs/foo() {/foo(var) {/
であり、エスケープする理由がなかったため、スクリプトは実行し(
ませんでした。したがって、新しい\(
or \{
演算子を導入しても下位互換性は損なわれません。古い構文を使用して既存のスクリプトを壊す可能性は非常に低いからです。
だから、それが行われたことです。その後、\(...\)
唯一のために最初に追加されましたs
ed
ようなことを行うには、コマンドs/foo\(.\)/\1bar/
以降としてgrep '\(.\)\1'
(しかし、好きではないものを土台\(xx\)*
)。
(その約10年後の1979年、)UnixV7では、正規表現の新しい形、新しい中に追加されましたegrep
し、awk
(彼らは新しいツールであるため、壊れすべき下位互換性はありません)拡張正規表現と呼ばれるユーティリティ。最後に、それはケン・トンプソンの古代で利用可能な機能を提供するqed
(選択演算子|
、グループ化(..)*
)など、いくつかの演算子を追加+
し、?
(基本的な正規表現の後方参照の機能を持っていませんでした)。
後のBSDを添加\<
し、\>
(BREとEREの両方に)、およびSysVを加え\{
と\}
のみBREではします。
このような下位互換性の破壊により、{
それ}
はEREに追加されてからかなり遅くなりました。誰もがそれを追加したわけではありません。たとえば、awk
バージョン4.0.0(2011)までのGNUは、{
POSIX準拠モードに強制されない限りサポートしませんでした。
GNU grep
が90年代の初めに書かれたとき、それはBSDとSysVの両方からすべての利点を追加しました(\<
、など{
)。(
、?
、{
、+
(他のBREの実装と互換性があるように)バックスラッシュが先行されなければなりません。それはあなたが行うことができます理由です.\+
GNUにgrep
(つまり、POSIXではないか、他の実装でサポートされているが)、あなたが行うことができます(.)\1
GNUでegrep
(つまり、POSIXではないか、GNUを含む多くの他の実装でサポートされているがawk
)。
\x
演算子の追加は、下位互換性のある方法で演算子を追加する唯一の方法ではありません。たとえば、perl
使用され(?...)
ます。(?=...)
EREでは無効であるため、これはEREとの下位互換性があります.*?
。vim
同様の事業者の場合は、\@=
または.\{-}
を導入するなどして、別の方法で行いました。