2

2 つの正規表現があるとします。

1234.*

.*

入力:

1234567

明らかに両方とも一致しますが、1234.* の方がより具体的であるため、より一致します。つまり、より関連性があります。どちらがより関連性が高いかを確認する標準的な方法はありますか?

編集:

いくつかの説明。どの正規表現が入力に最もよく一致するかを確認して決定を下したいと思います。この場合、私は数字を一致させるだけです。

電話番号の例:

入力:

31882481337

次の各正規表現にはルールがあります。

31.*
.*

このシナリオでは、31.* にバインドされたルールを使用したいと思います。これは、与えられた入力に対してより具体的であるためです。正規表現を使用していない場合は、スコアリング メカニズムを使用してどの程度一致するかを確認できるので簡単ですが、これらのルールには次のようなより高度な正規表現が含まれる場合があります。

31[89].*
4

4 に答える 4

4

これを行う簡単な方法はないと思います。より複雑な例を見ると、「より関連性が高い」を正確に定義するのは非常に難しいことがすぐにわかります。アサーションや後方参照などのすべてが機能します。

「関連性」を大まかに見積もるには、2 つの方法が考えられます。

  1. 入力をランダムに変更し、各式が失敗する原因となる変更の数を比較します。

  2. 式自体を分析します。終端記号とワイルドカードの数、アサーションの数など、好きなものを数えて比較します。

特に 2 番目のソリューションでは、実際のマッチングで使用されない多くの代替案が結果を無関係にする可能性があることに注意する必要があります。

h.*|verylongtext|anotherverylongtext

hell.*|v.*

「hello」に一致する場合、2 番目の表現は「関連性が高い」ですが、最初の表現にはより多くの終端記号が含まれており、2 番目のソリューションによってより良いランキングが得られる可能性があります。しかし、「非常に長いテキスト」に一致する場合は、最初のほうが「関連性が高い」です。これは、「関連性」が実際の入力に大きく依存していることを示しており、実際の一致パスを分析する必要があります。これは、最初のソリューションによって暗黙的に行われます。しかし、可能な入力のスペースが非常に大きいため、入力をランダムに変更することは非常に難しい作業です。これもなかなかうまくいかないと思います。

于 2009-07-14T20:51:17.950 に答える
1

私が考えることができる 1 つの要因は、言語が無限かどうかです。言語には有限の数の受け入れ可能な単語があるため、無限ではないことは無限よりも間違いなく関連性があります。

あなたの例のような無限の言語を測定する場合、どちらも永遠に続き、顔​​が青くなるまで言語の各単語を数え続けることができます。結論に達することはありません.

最初の正規表現の言語が 2 番目の言語の適切なサブセットであると考えるまで。その場合、1 つがより関連性が高いと言えます。

正規表現の関連性を測定する方法については、標準はわかりません。

適切なサブセットのアイデアを説明するために、あなたの言語は何ですか? 正規表現はそれ以外の単語を受け入れますか? あなたの表現はまだ機能するかもしれませんが、意図したよりも広い範囲の単語が含まれています... もちろん、入力が制御されている場合、これは問題にならないかもしれませんが、それは関連性を測定できる 1 つの方法です。私の言語を正確に受け入れていますか?

あなたのは良い例です。おそらく、1234 で始まる数字を受け入れたいと思うでしょう。1234.*魅力的に機能します...しかし、それはあなたが指定した言語ではありません。`1234\d* はより具体的で、指定した言語と正確に一致するため、関連性が高くなります。

ただし、これはすべて純粋に理論的な観点からのものであり、ある正規表現が別の正規表現よりも優れているかどうかをプログラムで判断するのにはおそらくあまり役​​立ちません。

于 2009-07-14T20:50:27.733 に答える
1

この質問をしてから長い時間が経ちましたが、最終的に思いついたことをお知らせしたいと思います。私ははるかに単純なアプローチを採用しました。正規表現に重み係数を追加しただけです。したがって、正規表現を使用して定義しようとするのではなく、正規表現の関連性を自分で定義したと言えます。

Expression      Relevance
31.*              1
.*              0
于 2010-12-14T12:55:14.873 に答える
0

「関連性」が本当の問題かどうかはわかりません。あなたが示唆するように、それぞれが関連しており、それぞれが「1234567」と一致します。ただし、あなたも言うように、1 つ (「1234.*」) がより具体的です。正規表現を使用すると、特定性が高く (このような単純なケースでは)、最終的に (正規表現) が必要ないことに気付くまで、特定性に磨きをかけることができます。正規表現のルール 1: 必要がない場合は使用しないでください。たとえば、「1234567」に一致させるには、次のようにします。

$source = '1234567';
if ( stripos( $source, '1234' ) === 0 ) {
  $foo = substr( $source, 4 );
  // $source began with '1234' and $foo holds the rest
} else {
  // it didn't begin with '1234'
}

これは PHP の例ですが、受け入れられた値を非常に厳密に磨いたので、PCRE はもう必要ないという考えです。「関連性」は正規表現についてあまり多くを教えてくれませんが (このコンテキストで「関連性」をどのように定義しますか?)、具体性はより客観的な測定値であり、代わりに非正規表現の文字列関数を使用できると確信しています。非常に具体的であるためです(実際、これはブール値です-正規表現はありますか?)。

方程式から正規表現を減らすことができる以外: 与えられた正規表現の特異性を測定するには、式を満たす異なる値の数を (必要に応じてヒューリスティックに) 単純に比較します。このテストでスコアが最も低い式が、最も具体的であることが証明されます。

于 2009-07-14T21:18:07.847 に答える