1

正規表現のいくつかの実装は、微妙な点で互いに異なります。これは、それらを使用しようとすると、多くの混乱の原因となります。

これらの違いのほとんどには、文字がエスケープされるかどうかに関連するセマンティクスが含まれます。これはほとんどの場合、括弧の問題ですが、中括弧などにも当てはまります。これはおそらく、実装が見つかった言語または環境の構文の結果です。たとえば、$シンボルがある言語で変数名を示している場合、その言語で表現されている正規表現では、「行末」アンカー\$などをエスケープする必要があると予想できます。しかし、ここで混乱するのは、実際のドル記号をどのように表すかということです。Perl は正規表現をスラッシュで囲むことでこれを回避していると思います/

同様に、特定の文字自体のエスケープがあります。たとえば、\nやなどの印刷されない文字\tです。\d次に、数字や\s空白など、似たように見える一般的な文字グループがあり、数字\wだけでなくアンダースコアもカバーしていることを学びました。私は何度か\a「アルファベット」グループに使用しようとしていることに気付きましたが、これはベル文字 0x07 に一致するだけでした。

無数の正規表現の実装によって提供される機能と構文のすべての違いを理解するための単純で 1 回限りの解決策がないことは明らかです。テーブル。これはまさにこの一例vimですが、sedもちろん、私が広く使用しているプログラムのいくつかはカバーしていません.これもあり、「ワイルドカード」と呼ばれます)には、単純な正規表現の実装もあります。

私が望むのは、特定の正規表現実装に対して、その「エスケープ設定」が1つ(またはいくつかの) クエリ。

テストケースと巨大な正規表現クエリを含むファイルを作成し、それを一度実行すると、後で使用する必要がある構文が正確に表示されるように設計できると考えています。(ファイルを編集し、複数のクエリを使用して、しばらくするとひどく古くなる同じものを把握する必要があるのとは対照的に)。

誰もそのような怪物を構築しようと試みていない場合、私はこの仕事を自分で引き受けるかもしれません. それさえ可能なら。これは可能ですか?

私は例を考え出そうとしました (EOL アンカーが$またはであるかを把握するためだけでした\$) が、どの場合でも、プログラムが入力にどのように応答するかを判断するために、多数の異なる検索/置換クエリを使用する必要がありました。

編集:キャプチャとバックトラッキングを使用して何かを思いつきました。もう少し取り組まなきゃ。

更新: Notepad++ は、一般に pipe で示される OR 演算子を実装していません||Word の「ワイルドカード」も代用としては不十分で、 orがありません*。正規表現演算子 (union、concat、star) のいずれかが欠落しているということは、通常の文法を生成できないことを意味するので、これら 2 つが除外されることはほぼ確実です。

次のような入力ファイルを作成できます。

$
*
]
EOL

とクエリ

(\$)|(\*)|(\[)|($)

で置き換える

escDollar:\1:escStar:\2:escSQBrL:\3:Dollar:\4:

(エスケープされていない括弧がグループで、エスケープされていないパイプが or であると仮定すると) の結果が得られます。

escDollar:$:escStar::escSQBrL::Dollar::
escDollar::escStar:*:escSQBrL::Dollar::
]escDollar::escStar::escSQBrL::Dollar::
EOLescDollar::escStar::escSQBrL::Dollar::

私はこれを実行しましたvim。この出力は、次に指定された各項目と一致する単一文字を示します。つまり、エスケープされたドル記号項目は、末尾のエスケープされていないドル記号項目ではなく、実際のドル記号文字と一致するように見えます。

ゼロ文字に一致するため、アンカーで何が起こっているかを確認するのは困難$ですが、解決策を見つけるのは難しくありません。その上、それは一般的に誤解されているものではありません。私が特に心配しているのは、パイプと括弧とさまざまな括弧です。4 つの異なる型がある場合、それらのエスケープされたバージョンとエスケープされていないバージョンの 2^4 の組み合わせを使用できます。その試行錯誤は恐ろしいものです。

この出力は、一目で解析するのはそれほど難しくなく、スクリプトの一部として処理するのも非常に簡単です。残っている明白な問題の 1 つは、括弧とパイプをエスケープする必要があるかどうかを判断することです。全体の機能はそれらに依存するためです。

複数のクエリが必要になるようです。バックスラッシュ、括弧、およびパイプの巧妙に設計された寄せ集めにより、最初のクエリとの組み合わせ (最終的には 4 つの可能性のみ) を見つけ出し、それに基づいて後続のマトリックス ジェネレーター クエリを選択することが可能になる場合があります。

このようなものは、それが機能することを示しています:

(e)
(f)

クエリ

\((f\))|\|\((e\))

と置換する

\1:\2

生成されます:

  • :(eエスケープされた括弧がグループで、エスケープされたパイプが or の場合
  • :e)括弧がグループで、エスケープされたパイプが or の場合
  • (f:エスケープされた括弧がグループで、パイプが or の場合
  • f):括弧がグループで、パイプが or の場合

ただし、2 番目の入力セットに対して 2 番目のクエリが必要になるため、これはまだあまり好きではありません。設定しすぎ。「マトリックス」のコピーを4つ作るだけかもしれません。

4

1 に答える 1