0

私には特別な要件があります。私の正規表現パターンは実行時に決定されます。たとえば、日付があり、それをチェックしたい、またはmm-dd-yyyy基本的に何かをパターンに入力します。ここで、数値と文字を意味し、表現は何でも構いません。この種の要件を満たす正規表現を記述できますか?mm/dd/yyyyd.mm.yyyyNN-NN-TTTTNT

私のフォームは、 http://jsfiddle.net/E2EHZ/に表示されるようになります。データは、テキスト ボックスで指定されたパターンに対応して一致します。

T- 文字
N- 数値
A- 英数字

4

1 に答える 1

3

したがって、基本的に、ユーザーに を含むパターンを入力させるかT、文字どおり間に一致させる必要がある他の文字のプレースホルダーとして入力させるのでしょうか? もしそうなら、それはかなり簡単です:プレースホルダーを適切な文字クラスに置き換え、残りを引用して(正規表現のメタ文字がエスケープされるように)、結果を正規表現として使用します。NA

、またはでない ものはすべて最初にエスケープします。これを行う方法は言語によって異なりますが、基本的には一致のエスケープ バージョンに置き換えます。C# では、次のようになります。ANT[^ANT]+

Regex.Replace(s, "[^ANT]+", m => Regex.Escape(m.Value));

またはJavaで:

s.replaceAll("[^ANT]+", "\\Q$0\\E"

次に実行する翻訳は簡単です。

T → [a-zA-Z]
N → [0-9]
A → [0-9a-zA-Z]

つまり、ASCII のみを想定しています。あなたが望むかもしれないユニコードのために

T → \p{L}
N → \p{Nd}
A → [\p{L}\p{Nd}]

代わりは。また、単純な文字列置換を実行する場合は、A最初に ASCII バージョンに置き換え、N最初に Unicode バリアントに置き換えて、後続の結果で置き換えないようにする必要があることに注意してください。

最後に、完全な文字列に一致させたい場合は、文字列のプレフィックス^とサフィックスを付けたい場合があります。$

C# でのサンプル実装 (わずかな最適化あり):

string CreateRegex(string pattern) {
  string result = Regex.Replace(pattern, "[^ANT]+", m => Regex.Escape(m.Value));
  result = Regex.Replace(result, "A+", m => "[0-9a-zA-Z]" + (m.Length > 1 ? "{"+m.Length+"}" : ""));
  result = Regex.Replace(result, "T+", m => "[a-zA-Z]" + (m.Length > 1 ? "{"+m.Length+"}" : ""));
  result = Regex.Replace(result, "N+", m => "[0-9]" + (m.Length > 1 ? "{"+m.Length+"}" : ""));
  return "^" + result + "$";
}

たとえば、次のようになります。

NN-NN-TTTT → ^[0-9]{2}-[0-9]{2}-[a-zA-Z]{4}$
*(@&#^(&%(@  AA-AA-NN-TTTTTTTT lreglig → \*\(@&\#\^\(&%\(@\ \ [0-9a-zA-Z]{2}-[0-9a-zA-Z]{2}-[0-9]{2}-[a-zA-Z]{8}\ lreglig

または Java の場合 (関数を置換として使用する方法がわからないため、前述の最適化なし):

String createRegex(String pattern) {
  String result = pattern.replaceAll("[^ANT]+", "\\Q$0\\E");
  result = result.replaceAll("A", "[0-9a-zA-Z]");
  result = result.replaceAll("T", "[a-zA-Z]");
  result = result.replaceAll("N", "[0-9]");
  return "^" + result + "$";
}

上記のコードは同一のトークンに対して繰り返しを使用しないため、結果の正規表現は少し長くなります。

于 2012-08-03T08:12:13.750 に答える