我有一个特殊要求,我的正则表达式模式将在运行时确定,表示我有一个日期,并希望根据mm-dd-yyyy
或mm/dd/yyyy
或d.mm.yyyy
进行检查基本上我会将模式作为NN-NN-TTTT
提供,其中N
表示数字,T
表示字母,表达式可以是任何字母。我们可以编写任何适用于此类要求的正则表达式吗?
我的表单看起来像http://jsfiddle.net/E2EHZ/中显示的数据将匹配对应于文本框中指定的模式
T
- 信
N
- 数字
A
- Alphanum
答案 0 :(得分:3)
所以基本上你会让你的用户输入一个包含T
,N
或A
的模式作为占位符,其他字符需要在两者之间进行字面匹配?如果是这样,那么它很容易:只需用适当的字符类替换占位符,引用其余的(因此转义正则表达式元字符)并将结果用作正则表达式。
不 A
,N
或T
的首次逃避。如何执行此操作因语言而异,但基本上您可以使用转义版本的匹配替换[^ANT]+
。在C#中,它可能如下所示:
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。对于Unicode,您可能需要
T → \p{L}
N → \p{Nd}
A → [\p{L}\p{Nd}]
代替。另请注意,如果执行简单的字符串替换,则需要首先使用ASCII版本替换A
,然后首先将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 + "$";
}
由此产生的正则表达式会更长一些,因为上面的代码不会对相同的标记使用重复。