正規表現でエスケープする必要がある特殊文字は何ですか?


389

()[]{}|正規表現の多くの実装を使用しているときに「」などの特殊文字をエスケープする必要があるかどうか、常に推測しようとすることにうんざりしています。

たとえば、Python、sed、grep、awk、Perl、rename、Apache、findなどとは異なります。特殊文字をエスケープするタイミングとエスケープしないタイミングを示すルールセットはありますか?PCRE、POSIX、拡張正規表現などの正規表現タイプに依存しますか?


4
優れた正規表現ライブラリには、 " escape()"のような関数があり、任意の文字列を正規表現の部分として使用できます。
ivan_pozdeev 2013年

2
gskinner.com/RegExr(無料)などのオンラインRegex式チェッカーを使用できます。(入力してから、入力した正規表現の上にマウスを
置き

2
英数字以外のすべての文字をエスケープします。限目。
サルマンフォンアッバス

2
この質問は、「その他」の下のスタックオーバーフローの正規表現に関するFAQに追加されました。
aliteralmind 2014

1
この質問は、「エスケープシーケンス」のスタックオーバーフローの正規表現に関するFAQに追加されました。
aliteralmind 2014

回答:


365

実際にエスケープしてはならない文字とエスケープしてはならない文字は、使用している正規表現の種類によって異なります。

PCREおよび他のほとんどのいわゆるPerl互換フレーバーの場合、これらの外部文字クラスをエスケープします。

.^$*+?()[{\|

これらの内部文字クラス:

^-]\

POSIX拡張正規表現(ERE)の場合、これらの外部文字クラス(PCREと同じ)をエスケープします。

.^$*+?()[{\|

他の文字をエスケープすると、POSIX EREではエラーになります。

文字クラスの内部では、円記号はPOSIX正規表現のリテラル文字です。何かをエスケープするために使用することはできません。文字クラスのメタ文字をリテラルとして含める場合は、「賢い配置」を使用する必要があります。^を先頭以外の任意の場所に配置し、]を先頭に、-を文字クラスの先頭または末尾に配置して、これらを文字どおり一致させます。例:

[]^-]

POSIX基本正規表現(BRE)では、これらは、意味を抑制するためにエスケープする必要があるメタ文字です。

.^$*[\

BREで括弧と中括弧をエスケープすると、エスケープされていないバージョンがEREで持つ特別な意味が与えられます。いくつかの実装(たとえばGNU)は、エスケープされたときに他の文字に特別な意味を与えます(\?など)。と+。。^ $ *(){}以外の文字をエスケープすると、通常、BREのエラーになります。

文字クラス内では、BREはEREと同じルールに従います。

これがすべてあなたの頭を回転させるなら、RegexBuddyのコピーをつかんでください。[作成]タブで、[トークンの挿入]、[リテラル]の順にクリックします。RegexBuddyは必要に応じてエスケープを追加します。


1
クラスの外にエスケープする必要がある「/」を忘れたようです。
jackthehipster

11
/は、前述の正規表現フレーバーのメタキャラクターではないため、正規表現構文でエスケープする必要はありません。プログラミング言語で正規表現がリテラルとして引用されている場合、その言語の文字列または正規表現のフォーマットルールでは、エスケープする/"'エスケープする必要があります。また、\を二重にエスケープする必要がある場合もあります。
Jan Goyvaerts、2015

2
コロン「:」はどうですか?文字クラスの内部だけでなく外部でもエスケープされますか?en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressionsは、「PCREには一貫したエスケープルールがあります。英数字以外の文字は、そのリテラル値[...]を意味するためにエスケープできます」
nicolallias

4
エスケープしてもよいですが、エスケープする必要があります。PCRE構文では、リテラルコロンをエスケープする必要はありません。したがって、リテラルコロンをエスケープすると、正規表現が読みにくくなるだけです。
Jan Goyvaerts、2015年

1
非POSIX ERE(Tclによって実装されているため、私が最も頻繁に使用するERE)の場合、他のものをエスケープしてもエラーは生成されません。
slebetman 2015

61

モダンRegExフレーバー(PCRE)

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の互換性は異なる場合があります

    どこでも: . ^ $ * + - ? ( ) [ ] { } \ |


レガシーRegExフレーバー(BRE / ERE)

awk、ed、egrep、emacs、GNUlib、grep、PHP(ereg)、MySQL、Oracle、R、sedが含まれます。
PCREサポートは、以降のバージョンで、または拡張機能を使用して有効にすることができます

ERE / awk / egrep / emacs

    文字クラスの外側:文字クラスの. ^ $ * + ? ( ) [ { } \ |
    内側:^ - [ ]

BRE / ed / grep / sed

    文字クラスの外側:文字クラスの. ^ $ * [ \
    内側:^ - [ ]
    リテラルの場合はエスケープしないでください:+ ? ( ) { } |
    標準の正規表現の動作の場合はエスケープしてください:\+ \? \( \) \{ \} \|


ノート

  • 特定の文字が不明な場合は、次のようにエスケープできます \xFF
  • 英数字はバックスラッシュでエスケープできません
  • PCREでは任意の記号をバックスラッシュでエスケープできますが、BRE / EREはエスケープできません(必要な場合にのみエスケープする必要があります)。PCREの] -場合、文字クラス内でのみエスケープする必要がありますが、簡単にするために、それらを1つのリストにまとめました。
  • 引用符で囲まれた表現の文字列は、周囲の引用符をエスケープし、多くの場合、バックスラッシュと二倍アップ(のように持っている必要があります"(\")(/)(\\.)"/(")(\/)(\.)/JavaScriptで)
  • エスケープは別として、さまざまな正規表現の実装は、さまざまな修飾子、文字クラス、アンカー、数量詞、およびその他の機能をサポートする場合があります。詳細については、regular-expressions.infoを確認するregex101.comを使用して式をライブでテストしてください

1
回答に多くのエラーがありますが、これらに限定されません。「モダン」なフレーバーのいずれも、文字クラスの外でエスケープする必要が-ないか]、エスケープする必要はありません。POSIX(BRE / ERE)には、文字クラス内にエスケープ文字がありません。DelphiのRTLの正規表現は、実際にはPCREに基づいています。Python、Ruby、およびXMLには、POSIXフレーバーよりもPCREに近い独自のフレーバーがあります。
Jan Goyvaerts 2017

1
@JanGoyvaerts訂正ありがとうございます。あなたが言及した味は確かにPCREに近いです。エスケープについては、簡単にするためにそのようにしておいた。いくつかの例外を除いて、どこにでも逃げることを覚えている方が簡単です。パワーユーザーは、バックスラッシュをいくつか避けたい場合は、何が起きているかを知ることができます。とにかく、私は私の答えをいくつかの明確化で更新しました。
Beejor 2017年

22

残念ながら、使用している言語によって異なるため、実際には一連のエスケープコードはありません。

ただし、正規表現ツールページやこの正規表現チートシートのようなページを維持すると、物事をすばやくフィルターで除外するのに役立つ場合があります。


1
Addedbytesのチートシートは著しく単純化されており、いくつかの明白なエラーがあります。例えば、それは言う\<\>ブースト正規表現ライブラリに(私の知る限り)唯一の真実である単語の境界、です。しかし、他の場所では<それ>はメタキャラクターであり、メタキャラクターであり、それらを文字どおり一致させるにはエスケープする必要があります(\<および\>)。これはどのフレーバーにも当てはまりません
アランムーア

5

残念ながら、(や\(など)の意味は、Emacsスタイルの正規表現と他のほとんどのスタイルの間で入れ替わっています。したがって、これらをエスケープしようとすると、希望とは逆のことをする可能性があります。

だからあなたは本当にあなたが引用しようとしているスタイルを知っている必要があります。


5

POSIXは、正規表現の複数のバリエーションを認識します-基本正規表現(BRE)と拡張正規表現(ERE)。そしてそれでも、POSIXによって標準化されたユーティリティの歴史的な実装のために、癖があります。

どの表記を使用するか、または特定のコマンドがどの表記を使用するかについての簡単なルールはありません。

Jeff FriedlのMastering Regular Expressionsの本をご覧ください。


4

本当にありません。約50億の異なる正規表現構文があります。彼らは一般にPerl、EMACS / GNU、AT&Tに分類されるように見えますが、私もいつも驚いています。


4

リストした文字では、単純なエスケープができない場合があります。たとえば、バックスラッシュを使用して角かっこをエスケープしても、sedの置換文字列の左側では機能しません。

sed -e 's/foo\(bar/something_else/'

代わりに単純な文字クラス定義を使用する傾向があるため、上記の式は

sed -e 's/foo[(]bar/something_else/'

ほとんどの正規表現の実装で動作します。

ところで、文字クラスはかなりバニラの正規表現コンポーネントなので、正規表現でエスケープ文字が必要なほとんどの状況で機能する傾向があります。

編集:以下のコメントの後で、正規表現の評価の動作を見るときに、有限状態オートマトンと非有限状態オートマトンの違いも考慮する必要があるという事実に言及したいと思いました。

"光沢のあるボールブック"別名Effective Perl(Amazonのサニタイズされたリンク)、特に正規表現の章を見て、正規表現エンジンの評価タイプの違いを感じてください。

すべてが世界のPCREであるとは限りません!

とにかく、正規表現はSNOBOLに比べてとても不格好です!今、それは興味深いプログラミングのコースでした!Simulaのものと一緒に。

ああ、70年代後半のUNSWでの勉強の喜び!(-:


'sed'は、単純な '('は特別ではありませんが、 '\('は特別ですが、逆にPCREが意味を逆にするため、 '('は特別ですが、 '\('は特別ではありません。 OPが尋ねています
ジョナサンレフラー

sedは、正規表現評価の最も原始的なセットの1つを使用する* nixユーティリティです。PCREは、正規表現を評価する方法とは異なるクラスの(非)有限オートマトンを含むため、私が説明する状況には入りません。正規表現構文の最小限のセットに対する私の提案はまだ保持されていると思います。
ロブ・ウェルズ

1
POSIX準拠のシステムでは、sedはPOSIX BREを使用します。最新のLinuxシステムのGNUバージョンは、いくつかの拡張機能を備えたPOSIX BREを使用しています。
Jan Goyvaerts、2008

2

PHPの場合、「英数字以外の前に「\」を付けて、それ自体を表すことは常に安全です。」- http://php.net/manual/en/regexp.reference.escape.php

"または 'である場合を除きます。:/

PHPで正規表現パターン変数(または部分変数)をエスケープするには、preg_quote()を使用します


2

文字列が通過する一連のコンテキストを正確に理解するには、試行せずにいつ、何をエスケープするかを知る必要があります。最も遠い側から最終的な宛先までの文字列を指定します。これは、正規表現解析コードによって処理されるメモリです。

メモリ内の文字列がどのように処理されるかに注意してください。コード内のプレーンな文字列、またはコマンドラインに入力された文字列である場合がありますが、対話型のコマンドラインまたはシェルスクリプトファイル内に記述されたコマンドラインの場合があります。コードで言及されたメモリ内の変数内、またはさらに評価された(文字列)引数、または任意の種類のカプセル化で動的に生成されたコードを含む文字列...

この各コンテキストは、特別な機能を持ついくつかのキャラクターを割り当てました。

特別な関数(コンテキストに対してローカル)を使用せずに文字を文字通りに渡したい場合は、次のコンテキストのためにエスケープする必要がある場合よりも、追加のエスケープ文字が必要になる可能性があります。前のコンテキストでエスケープされました。さらに、文字エンコーディングのようなものも存在する可能性があります(最も潜んでいるのは、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:...)。

他の回答の文字についての詳細があり、これは最終的な正規表現コンテキストに非常に固有です。試行で正規表現エスケープを見つけたと述べたように、これはおそらく、異なるコンテキストに試行の記憶を混乱させる異なる文字セットがあるためです(多くの場合、バックスラッシュは、関数の代わりにリテラル文字をエスケープするためにそれらの異なるコンテキストで使用される文字です) )。



0

Ionic(Typescript)の場合、文字をエスケープするためにダブルスラッシュを使用する必要があります。例(これは一部の特殊文字に一致させるためです):

"^(?=.*[\\]\\[!¡\'=ªº\\-\\_ç@#$%^&*(),;\\.?\":{}|<>\+\\/])"

この] [ - _ . /キャラクターに注意してください。それらはダブルスラッシュにする必要があります。そうしないと、コードに型エラーが発生します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.