![bash正規表現が\ bをサポートしていない理由はありますか? [コピー]](https://linux33.com/image/230064/bash%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE%E3%81%8C%5C%20b%E3%82%92%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%97%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E7%90%86%E7%94%B1%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F%20%5B%E3%82%B3%E3%83%94%E3%83%BC%5D.png)
私が知る限り、\b
bashは「単語の境界」を表すメタシーケンスをサポートしません。
if [[ $foo =~ .*\bWORD\b.* ]]; then
この機能がサポートされていない理由はありますか?
bashのパッチ/プール要求を作成すると想像してください。実装できない理由はありますか\b
(「この機能が気に入らない」などを除く)?
答え1
~によるとbash
マニュアルページ、この=~
演算子はPOSIX正規表現関数を使用しているようです。
演算子を使用すると、
=~
右側の文字列はPOSIX拡張正規表現パターンとして扱われ、それに応じて一致します(POSIXregcomp
および一般的に説明されているインタフェースを使用)。regexec
regex(3)
メタ\b
シーケンスはPerl正規表現構文POSIXの一部ではないため、Bashで使用されるライブラリはそれをサポートしていないようです。したがって、Bashでこれをサポートすることは、ライブラリを変更することを意味する可能性があり、これはしばしば深刻な副作用を引き起こします。
これは純粋に文法的要素に対応するために行われたようではありません。
答え2
まず、Bashに独自のRE実装があるのか、システムライブラリのRE実装を使用しているのかを確認してください。
しかし、そうです。\b
一般に、Perl正規表現に由来する標準正規表現では使用できない他の拡張も多く含まれています。 GNUシステムは\s
スペースと単語の文字をサポートしているようですが、数字はサポートしていませ\w
ん\d
。なぜその奇妙なものを選ぶことにしたのかはわかりませんが、全体的に、みんなPerl RE機能はREエンジンをより複雑にすることができ、Perlファンはそれが好きですが、多くの標準ツール作成者はそれを望まないかもしれません。しかし、すべてではなく、これを追加し始めると、どこに線を引くべきかを決定することが問題になります。
とにかく、単語の境界は最初から非標準です。一部のシステムでは、\<
および\>
は左右の境界線に適用する必要がありますが、FreeBSDとMacではと[[:<:]]
が必要です[[:>:]]
。
偶然にも@steeldriverが述べたように、\b
少なくとも私がテストしたときにGNUでも動作するようです。 Bashでは、シェルの解析プロセスによって特殊文字が難読化されるのを防ぐために、まずREを変数に保存する必要があります。
$ re='\bWORD\b'; if [[ WORD =~ $re ]]; then echo y; else echo n; fi
y
$ re='\<WORD\>'; if [[ WORD =~ $re ]]; then echo y; else echo n; fi
y
$ re='\bWORD\b'; if [[ WORDLESS =~ $re ]]; then echo y; else echo n; fi
n
$ re='\<WORD\>'; if [[ WORDLESS =~ $re ]]; then echo y; else echo n; fi
n