正規表現の微妙さ。 パート1:文字クラスの内外のメタキャラクター

参加する代わりに





プログラムを書いたことのある人なら誰でも、正規表現のような奇跡が世界にあることを知っています。 それらなしでは一歩踏み出せない人もいれば、火のように恐れている人もいますが、正規表現のない現代のプログラミング言語を想像するのは非常に困難です。



初心者プログラマーが初めて正規表現について知るとどうなりますか? ほとんどの場合、最初の知り合いは「科学的な突く」方法を使用して行われます。これは、通常、対応する分野の知識も「仕組み」の理解も持たないためです。 なぜこれが起こっているのですか?







多くの人が正規表現に言及するときにPerl言語に言及するのは秘密ではありません。 無駄ではありません! Perlは、基本的な言語構成の構文レベルで正規表現が修正される数少ない言語の1つです。 同時に、Perlは、作成後5分でプログラムを理解するのが非常に難しい言語として有名になりました。 豊富な1〜2文字の関数と変数がその役割を果たします。 テキストは、プログラムというよりは絵文字のセットに似ています。 特に正規表現を使用する場合。



しかし、私はトピックから逸​​脱し、開始する時間がないように見えました。 そのため、正規表現とは何か、なぜ使用されるのかを既に知っていると仮定します。 さらに興味深いことに移りましょう。



正規表現の方言





歴史的に、正規表現は最初(そして今でも)厳密な標準化なしで開発されました。 もちろん、これにより、構文とセマンティクスに多くの違いが生じました。 現時点では、正規表現の構文は非常に似ており、近いと言えますが、まだ違いがあります。



もちろん、標準化などの重要な問題では、全能のPOSIXは完全ではありませんでした。 さらに、正規表現は、Unix環境でのみ発生します。



POSIXでは、正規表現の構文とセマンティクスについて説明しています。 主な標準は2つあります。POSIXBRE(基本正規表現)とPOSIX ERE(拡張正規表現)です。 名前が示すように、2番目の標準が最初の標準を拡張するという点で異なります。 各標準に含まれる内容、特にそれらに含まれる内容のセマンティクスについては、Wikipediaで常に確認できるため、詳細には説明しません。 そのような標準が存在するという事実にもかかわらず、正規表現エンジンの開発者はそれらを完全に追うことを急ぐことはできません。 特にセマンティクスで! そして、正当な理由があります。



それで、異なる言語とユーティリティの正規表現方言の違いは何ですか? これは、もちろん、主にメタキャラクター(文字通りの意味ではなく、特別な方法で解釈されるキャラクター)です。



たとえば、非常に一般的に使用されるメタキャラクターを考えてみましょう.



(期間)。 おそらく、これまでに正規表現に出会ったことのある人なら誰でも、このメタキャラクターが「任意のキャラクター」を意味することを知っているでしょう。 はい、しかし彼はそれを意味しません! メタ文字「ドット」は、「行末以外の任意の文字」として解釈されます。 しかし、再び、どこでもない。 一部の言語では、デフォルトの解釈はこれであり、他の言語では単なる「任意の文字」であり、多くの場合、この解釈とその解釈のモードがあります。



次のよくある違いは、括弧の解釈です。 カーリー、ラウンド、スクエア。 どこかで括弧を引用する必要があり、どこかで引用する必要はありません。 たとえば、.NET、Javaでは、角かっこはメタ文字であるため、引用符で囲む必要があります。 grepユーティリティは、デフォルトで引用符を引用する必要はありません! また、グループなどの機能を使用するには、 \(\)



形式の式を使用する必要があります。



文字クラス内のメタキャラクター





そしてすぐに、メタキャラクターについては忘れていません。シンボルクラスを検討してください。 初心者にとって非常によくある間違いは、文字クラス内のメタキャラクターを引用することです。 多くの場合、そのような間違いは結果をもたらさないことがよくあります(多くの場合)が、シンボルクラスがどのように機能するかを人が完全に理解していないことは明らかです。



文字クラスは、正規表現を使用したすべての人が遭遇しました。 私はそれを確信しています。 私たちがアマチュアの言語を話せば、それが何であるかを忘れた人のために、私に思い出させてください-文字クラスは角括弧内のシーケンスです。 例: [abc0-9]



-文字クラスが一致する場所には、文字aまたはb、c、または0〜9の数字が存在する必要があります。



しかし、私たちが望むほど簡単ではありません。 最初に覚えておくべきこと:キャラクタークラスは異なる世界です! 角かっこに入ると、ゲームのすべてのルールが変わります。 一部のメタキャラクターはそのようなものではなくなり、他のメタキャラクターのセマンティクスは根本的に変わります。 根拠にならないように、例を挙げます。





他のメタキャラクターは、スペースの不足については考慮しません。 [\.\(\)\{\^]



と書く必要がない理由が明らかになりました。 文字クラス内のこれらのメタキャラクターがもはやそうではないからです。 そして、「万が一に備えて」それらを引用すると、あなたは自分が内部で何が起こっているのか本当に理解していないことを示します。



記事は意外と大きい。 正規表現の実装の違い、実装のセマンティクスの違い、シンボルクラスの解釈の違い、および一般的な解釈方法について書きたいと思いました。 したがって、私は今のところそのような記事を残すと思います、そしてあなたがそれを好めば、私は以下を書くでしょう。



本「 Jeffrey Friedl、Mastering Regular Expressions 」に基づいています。

パート2



All Articles