
たとえば、Debian または Debian 派生システムのツールを使用すると、空のN*
文字列に一致する次の正規表現を sed で一致させることができます。
$ echo 'Hello' | sed 's/N*/ xx&xx /g'
xxxx H xxxx e xxxx l xxxx l xxxx o xxxx
xxxx
これは、各文字列文字の前の空の一致(つまり、間に文字がない文字列)の正しい結果ですxx&xx
(から6回Hello
。末尾の改行は計算されず、一致しません)。
xx
そして、文字(または文字グループ)が一致すると、および間に表示されますxx
。
$ echo 'Hello' | sed 's/e*/ xx&xx /g'
xxxx H xxexx l xxxx l xxxx o xxxx
しかし、grepの同じ正規表現はいいえ空の文字列と一致します。
$ echo 'Hello' | grep -o 'N*'
しかし印刷します。ただ空でない一致:
$ echo 'Hello' | grep -o 'e*'
e
正規表現の一致を避けるためにgrepに追加の内部ルールがありますかempty
?
答え1
grep -o
grep --help
次のように記録
-o, --only-matching show only nonempty parts of lines that match
そしてマニュアルに〜のように
一致する行の一致する(空でない)部分のみが印刷され、各部分は別々の出力行に表示されます。
はい。追加のルールがありますgrep -o
。一致が空でない場合のみ出力されます。
ではecho 'Hello' | grep -o 'N*'
正規表現は一致しますが(戻りコードを表示または使用してわかりますecho 'Hello' | grep 'N*'
)、一致は空であるため何も出力されません。
答え2
長さがゼロの文字列マッチングの動作は、コード内の特別なケースである場合とそうでない場合があります。例ではsed
ありませんが、perl
$ echo aabb | sed 's/a*/X/g'
XbXbX
$ echo aabb | gsed 's/a*/X/g'
XbXbX
$ echo aabb | perl -ple 's/a*/X/g'
XXbXbX
行動はviが歴史的にどのように行動したかに依存します。深さからわかるようにex/ex_subst.c
:
/*
* !!!
* It's possible to match 0-length strings -- for example, the
* command s;a*;X;, when matched against the string "aabb" will
* result in "XbXbX", i.e. the matches are "aa", the space
* between the b's and the space between the b's and the end of
* the string. There is a similar space between the beginning
* of the string and the a's. The rule that we use (because vi
* historically used it) is that any 0-length match, occurring
* immediately after a match, is ignored. Otherwise, the above
* example would have resulted in "XXbXbX". Another example is
* incorrectly using " *" to replace groups of spaces with one
* space.
(もう1つの問題は、幅0の一致が絶対一致しないことです。これを防ぐために、「次の文字に移動します...」コードを追加できると確信しています。後ろに誰かのCPUが数回100%に達し、彼の手のひらが額に触れました。 )
BSDとGNUはどちらも式ed
に失敗するので、s/a*/X/g
珍しい動作ex-vi
はsed
?
$ echo aabb > foo
$ ed foo
5
s/a*/X/g
?
s/a*/X
Xbb
Q
答え3
$ echo 'Hello' | grep -o 'N*'
$ echo $?
0
それする終了状態として示されているように、この入力行の空の部分文字列と一致します。 (たとえば、他のモードを使用すると、N
stdoutでは何も得られませんが、終了状態は1
、failureです。)
-o
そうしないように印刷空の一致がありますが、正規表現が入力行と一致するかどうかには関係ありません。 (はい、違いがわかります。空の文字列一致を印刷すると、各一致の後に改行が印刷されるため、プロンプトの前に空白行があります。または各一致に対して1つずつ6になります。)
それ以外の場合は、-o
一致する行全体を印刷します。
$ echo 'Hello' | grep 'N*' # same as grep '' empty pattern
Hello