正規表現バリアントの区別とテスト
-
27-10-2019 - |
質問
正規表現のいくつかの実装は、微妙な方法で互いに異なります。
これらの違いのほとんどには、キャラクターが逃げられているかどうかに関連するセマンティクスが含まれます。これはほとんどの場合、括弧の問題ですが、巻き毛ブラケットなどに適用できます。これはおそらく、実装が見つかった言語または環境の構文の結果です。たとえば、 $
シンボルは、ある言語の変数名を示し、その言語で表される正規表現が「行の終わり」のアンカーを逃げる必要があると期待できます。 \$
またはそのようなもの。しかし、この時点で混乱するのは、実際のドルの標識をどのように表現するかです。私はPerlが前方のスラッシュに正規表現を包むことでこれを回避すると信じています /
.
同様に、特定のキャラクター自体には脱出があります。たとえば、例えば非印刷文字など \n
と \t
. 。次に、次のような見た目の一般的なキャラクターグループがあります \d
数字の場合、 \s
Whitespace用、および \w
私が学んだばかりのカバーのアンダースコアと数字も学びました。私は何度か使っていることに気づきました \a
「アルファベット順」グループの場合、これはベル文字0x07と一致するだけでした。
正規表現の無数の実装によって提供される機能と構文のすべての違いを知るための単純で1ショットのソリューションがないことは明らかです。テーブル。 ここ まさにこれの一例ですが、もちろん、私が自分で広く使用しているいくつかのプログラムをカバーしていません。 vim
, sed
, 、Notepad ++、Eclipse、そしてそれを信じているかどうかにかかわらず(少なくともバージョン2010、2007年もこれを「ワイルドカード」と呼んでいると思われます)。
私が望んでいるのは、特定の修復的実装を決定する方法を考え出そうとすることで、できるだけ怠け者になることだと思います。 )クエリ。
テストケースを含むファイルを作成し、巨大なRegexクエリを作成できると考えています。どういうわけかそれをエンジニアリングして、それを実行することで、それ以上自分自身を疑うことなくその後使用する必要がある構文を正確に示します。 (ファイルを編集し、複数のクエリを使用して、しばらくしてひどく古くなっているのと同じものを把握する必要があるのではなく)。
他の誰もそのような怪物を構築しようとしなかったなら、私は自分でこのタスクを引き受けるかもしれません。可能であれば。これは可能ですか?
私は例を考えようとしました(それはEOLアンカーがいるかどうかを理解するためだけでした $
また \$
)しかし、すべての場合において、プログラムが入力にどのように応答するかを判断するために、さまざまな検索/交換クエリを使用する必要がありました。
編集:キャプチャとバックトラッキングを使用して何かを思いつきました。もう少し作業しなければなりません。
更新:まあ、Notepad ++はパイプで一般的に示されるまたは一般的に示されるオペレーターを実装していません |
. 。 Wordの「ワイルドカード」も貧弱な代替品ですが、持っていません |
また *
. 。正規表現演算子(ユニオン、concat、星)のいずれかが不足していることは、通常の文法を生成できないことを意味するため、これら2つは除外されます。
このような入力ファイルを作成できます。
$
*
]
EOL
とクエリ
(\$)|(\*)|(\[)|($)
に置き換えます
escDollar:\1:escStar:\2:escSQBrL:\3:Dollar:\4:
の結果を生み出します(非脱型のパレンズがグループであり、無効なパイプがあると仮定します)
escDollar:$:escStar::escSQBrL::Dollar::
escDollar::escStar:*:escSQBrL::Dollar::
]escDollar::escStar::escSQBrL::Dollar::
EOLescDollar::escStar::escSQBrL::Dollar::
私はこれを実行しました vim
. 。この出力は、その隣に指定された各アイテムによって一致する単一の文字を示します。つまり、エスケープされたダラーサインアイテムは、最後に逃げられていないダラーサインアイテムではなく、実際のドルサイン文字に一致するように見えます。
何が起こっているのかを見るのは難しい $
アンカーはゼロ文字に一致しているためですが、解決策を見つけるのは難しくないはずです。それに加えて、それは一般的に間違ったものではありません。私が特に心配しているのは、パイプとパレンズとさまざまなブラケットです。そこに4つの異なるタイプがある場合、使用できるエスケープバージョンと非エスケープバージョンの2つの組み合わせがあります。それとの試行錯誤は恐ろしいです。
この出力は一目で解析するのがそれほど難しくなく、スクリプトの一部として非常に簡単に処理することもできます。残っている一つの明白な問題は、パレンズとパイプを逃れる必要があるかどうかを理解することです。全体の機能はそれらに依存しているためです。
複数のクエリが必要になるように思われます。巧妙に設計されたバックスラッシュ、パレンズ、パイプのごちゃごちゃで、最初のクエリを使用した組み合わせ(結局4つの可能性のみ)を把握することが可能かもしれません。その後、それに基づいた後続のマトリックスジェネレータークエリを選択します。
このようなことは、それが機能する可能性があることを示しています:
(e)
(f)
クエリ
\((f\))|\|\((e\))
と置換する
\1:\2
生産します:
:(e
脱出されたパレンズはグループであり、逃げたパイプは:e)
Parensがグループであり、脱出パイプがある場合(f:
脱出されたパレンズがグループであり、パイプはまたはですf):
Parensがグループであり、パイプがある場合
2番目の入力セットで2番目のクエリが必要であるため、私はまだこれが本当に好きではありません。セットアップが多すぎます。 「マトリックス」のものを4コピーするだけです。
解決
このページのテーブルは、Regexの実装が利用可能な機能を非常にうまくまとめています。