()[]{}|
正規表現の多くの実装を使用しているときに「」などの特殊文字をエスケープする必要があるかどうか、常に推測しようとすることにうんざりしています。
たとえば、Python、sed、grep、awk、Perl、rename、Apache、findなどとは異なります。特殊文字をエスケープするタイミングとエスケープしないタイミングを示すルールセットはありますか?PCRE、POSIX、拡張正規表現などの正規表現タイプに依存しますか?
()[]{}|
正規表現の多くの実装を使用しているときに「」などの特殊文字をエスケープする必要があるかどうか、常に推測しようとすることにうんざりしています。
たとえば、Python、sed、grep、awk、Perl、rename、Apache、findなどとは異なります。特殊文字をエスケープするタイミングとエスケープしないタイミングを示すルールセットはありますか?PCRE、POSIX、拡張正規表現などの正規表現タイプに依存しますか?
回答:
実際にエスケープしてはならない文字とエスケープしてはならない文字は、使用している正規表現の種類によって異なります。
PCREおよび他のほとんどのいわゆるPerl互換フレーバーの場合、これらの外部文字クラスをエスケープします。
.^$*+?()[{\|
これらの内部文字クラス:
^-]\
POSIX拡張正規表現(ERE)の場合、これらの外部文字クラス(PCREと同じ)をエスケープします。
.^$*+?()[{\|
他の文字をエスケープすると、POSIX EREではエラーになります。
文字クラスの内部では、円記号はPOSIX正規表現のリテラル文字です。何かをエスケープするために使用することはできません。文字クラスのメタ文字をリテラルとして含める場合は、「賢い配置」を使用する必要があります。^を先頭以外の任意の場所に配置し、]を先頭に、-を文字クラスの先頭または末尾に配置して、これらを文字どおり一致させます。例:
[]^-]
POSIX基本正規表現(BRE)では、これらは、意味を抑制するためにエスケープする必要があるメタ文字です。
.^$*[\
BREで括弧と中括弧をエスケープすると、エスケープされていないバージョンがEREで持つ特別な意味が与えられます。いくつかの実装(たとえばGNU)は、エスケープされたときに他の文字に特別な意味を与えます(\?など)。と+。。^ $ *(){}以外の文字をエスケープすると、通常、BREのエラーになります。
文字クラス内では、BREはEREと同じルールに従います。
これがすべてあなたの頭を回転させるなら、RegexBuddyのコピーをつかんでください。[作成]タブで、[トークンの挿入]、[リテラル]の順にクリックします。RegexBuddyは必要に応じてエスケープを追加します。
/
は、前述の正規表現フレーバーのメタキャラクターではないため、正規表現構文でエスケープする必要はありません。プログラミング言語で正規表現がリテラルとして引用されている場合、その言語の文字列または正規表現のフォーマットルールでは、エスケープする/
か"
、'
エスケープする必要があります。また、\を二重にエスケープする必要がある場合もあります。
C、C ++、Delphi、EditPad、Java、JavaScript、Perl、PHP(preg)、PostgreSQL、PowerGREP、PowerShell、Python、REALbasic、Real Studio、Ruby、TCL、VB.Net、VBScript、wxWidgets、XML Schema、Xojo、 XRegExp。
PCREの互換性は異なる場合があります
どこでも: . ^ $ * + - ? ( ) [ ] { } \ |
awk、ed、egrep、emacs、GNUlib、grep、PHP(ereg)、MySQL、Oracle、R、sedが含まれます。
PCREサポートは、以降のバージョンで、または拡張機能を使用して有効にすることができます
ERE / awk / egrep / emacs
文字クラスの外側:文字クラスの. ^ $ * + ? ( ) [ { } \ |
内側:^ - [ ]
BRE / ed / grep / sed
文字クラスの外側:文字クラスの. ^ $ * [ \
内側:^ - [ ]
リテラルの場合はエスケープしないでください:+ ? ( ) { } |
標準の正規表現の動作の場合はエスケープしてください:\+ \? \( \) \{ \} \|
\xFF
] -
場合、文字クラス内でのみエスケープする必要がありますが、簡単にするために、それらを1つのリストにまとめました。"(\")(/)(\\.)"
対/(")(\/)(\.)/
JavaScriptで)-
ないか]
、エスケープする必要はありません。POSIX(BRE / ERE)には、文字クラス内にエスケープ文字がありません。DelphiのRTLの正規表現は、実際にはPCREに基づいています。Python、Ruby、およびXMLには、POSIXフレーバーよりもPCREに近い独自のフレーバーがあります。
残念ながら、使用している言語によって異なるため、実際には一連のエスケープコードはありません。
ただし、正規表現ツールページやこの正規表現チートシートのようなページを維持すると、物事をすばやくフィルターで除外するのに役立つ場合があります。
\<
と\>
ブースト正規表現ライブラリに(私の知る限り)唯一の真実である単語の境界、です。しかし、他の場所では<
それ>
はメタキャラクターであり、メタキャラクターであり、それらを文字どおり一致させるにはエスケープする必要があります(\<
および\>
)。これはどのフレーバーにも当てはまりません
POSIXは、正規表現の複数のバリエーションを認識します-基本正規表現(BRE)と拡張正規表現(ERE)。そしてそれでも、POSIXによって標準化されたユーティリティの歴史的な実装のために、癖があります。
どの表記を使用するか、または特定のコマンドがどの表記を使用するかについての簡単なルールはありません。
Jeff FriedlのMastering Regular Expressionsの本をご覧ください。
本当にありません。約50億の異なる正規表現構文があります。彼らは一般にPerl、EMACS / GNU、AT&Tに分類されるように見えますが、私もいつも驚いています。
リストした文字では、単純なエスケープができない場合があります。たとえば、バックスラッシュを使用して角かっこをエスケープしても、sedの置換文字列の左側では機能しません。
sed -e 's/foo\(bar/something_else/'
代わりに単純な文字クラス定義を使用する傾向があるため、上記の式は
sed -e 's/foo[(]bar/something_else/'
ほとんどの正規表現の実装で動作します。
ところで、文字クラスはかなりバニラの正規表現コンポーネントなので、正規表現でエスケープ文字が必要なほとんどの状況で機能する傾向があります。
編集:以下のコメントの後で、正規表現の評価の動作を見るときに、有限状態オートマトンと非有限状態オートマトンの違いも考慮する必要があるという事実に言及したいと思いました。
"光沢のあるボールブック"別名Effective Perl(Amazonのサニタイズされたリンク)、特に正規表現の章を見て、正規表現エンジンの評価タイプの違いを感じてください。
すべてが世界のPCREであるとは限りません!
とにかく、正規表現はSNOBOLに比べてとても不格好です!今、それは興味深いプログラミングのコースでした!Simulaのものと一緒に。
ああ、70年代後半のUNSWでの勉強の喜び!(-:
PHPの場合、「英数字以外の前に「\」を付けて、それ自体を表すことは常に安全です。」- http://php.net/manual/en/regexp.reference.escape.php。
"または 'である場合を除きます。:/
PHPで正規表現パターン変数(または部分変数)をエスケープするには、preg_quote()を使用します
文字列が通過する一連のコンテキストを正確に理解するには、試行せずにいつ、何をエスケープするかを知る必要があります。最も遠い側から最終的な宛先までの文字列を指定します。これは、正規表現解析コードによって処理されるメモリです。
メモリ内の文字列がどのように処理されるかに注意してください。コード内のプレーンな文字列、またはコマンドラインに入力された文字列である場合がありますが、対話型のコマンドラインまたはシェルスクリプトファイル内に記述されたコマンドラインの場合があります。コードで言及されたメモリ内の変数内、またはさらに評価された(文字列)引数、または任意の種類のカプセル化で動的に生成されたコードを含む文字列...
この各コンテキストは、特別な機能を持ついくつかのキャラクターを割り当てました。
特別な関数(コンテキストに対してローカル)を使用せずに文字を文字通りに渡したい場合は、次のコンテキストのためにエスケープする必要がある場合よりも、追加のエスケープ文字が必要になる可能性があります。前のコンテキストでエスケープされました。さらに、文字エンコーディングのようなものも存在する可能性があります(最も潜んでいるのは、utf-8です。これは、一般的な文字はASCIIのように見えますが、設定によっては端末によってもオプションで解釈されるため、動作が異なる場合があり、HTMLのエンコーディング属性の場合もあります。 / XML、プロセスを正確に理解する必要があります。
たとえばperl -npe
、で始まるコマンドラインの正規表現は、ファイルハンドルをパイプとして接続する一連のexecシステムコールに転送する必要があります。このexecシステムコールのそれぞれには、(エスケープされていない)スペースで区切られた引数のリストがあります。そしておそらく、パイプ(|)やリダイレクト(> N> N>&M)、括弧のインタラクティブな拡大*
と?
、$(())
...(これはすべて、* shによって使用される特殊文字であり、次のコンテキストでは正規表現の文字と干渉する可能性がありますが、コマンドラインの前に順番に評価されます。コマンドラインは、 bash / sh / csh / tcsh / zshとしてプログラムします。基本的には二重引用符または単一引用符の内側でエスケープを行う方が簡単ですが、コマンドラインで文字列を引用符で囲む必要はありません。文字*と?の展開機能を利用可能にする必要はありませんが、これは引用符内とは異なるコンテキストとして解析されます。コマンドラインが評価されると、メモリで取得されたregexp(コマンドラインで記述されたものではない)はそれと同じ処理を受け取ります。はソースファイルにあります。正規表現の場合、角かっこ[]内に文字セットコンテキストがあります。perl正規表現は、英数字以外の文字の大きなセットで引用できます(例:m //またはm:/ better / for / path:...)。
他の回答の文字についての詳細があり、これは最終的な正規表現コンテキストに非常に固有です。試行で正規表現エスケープを見つけたと述べたように、これはおそらく、異なるコンテキストに試行の記憶を混乱させる異なる文字セットがあるためです(多くの場合、バックスラッシュは、関数の代わりにリテラル文字をエスケープするためにそれらの異なるコンテキストで使用される文字です) )。
https://perldoc.perl.org/perlre.html#Quoting-metacharactersおよびhttps://perldoc.perl.org/functions/quotemeta.html
公式ドキュメントでは、そのような文字はメタ文字と呼ばれています。引用の例:
my $regex = quotemeta($string)
s/$regex/something/
Ionic(Typescript)の場合、文字をエスケープするためにダブルスラッシュを使用する必要があります。例(これは一部の特殊文字に一致させるためです):
"^(?=.*[\\]\\[!¡\'=ªº\\-\\_ç@#$%^&*(),;\\.?\":{}|<>\+\\/])"
この] [ - _ . /
キャラクターに注意してください。それらはダブルスラッシュにする必要があります。そうしないと、コードに型エラーが発生します。
escape()
"のような関数があり、任意の文字列を正規表現の部分として使用できます。