Java 正则表达式查询(运行时可自定义)

Java 正则表达式查询(运行时可自定义),java,regex,Java,Regex,我有一个特殊的要求,我的正则表达式模式将在运行时确定,例如我有一个日期,并希望它与mm dd yyyy或mm/dd/yyyy或d.mm.yyyyy进行检查,基本上我将以NN-NN-TTTT的形式输入模式,其中N表示一个数字而T表示一个字母表达式可以是任何东西。我们可以编写任何正则表达式来满足这种需求吗 我的表单看起来就像在文本框中指定的模式对应的数据中显示的一样 T-字母 N-数字 A-Alphanum因此,基本上您可以让用户输入一个模式,其中包含T、N或A作为占位符,而其他字符需要在它们之间进

我有一个特殊的要求,我的正则表达式模式将在运行时确定,例如我有一个日期,并希望它与
mm dd yyyy
mm/dd/yyyy
d.mm.yyyyy
进行检查,基本上我将以
NN-NN-TTTT
的形式输入模式,其中
N
表示一个数字而
T
表示一个字母表达式可以是任何东西。我们可以编写任何正则表达式来满足这种需求吗

我的表单看起来就像在文本框中指定的模式对应的数据中显示的一样

T
-字母
N
-数字

A
-Alphanum

因此,基本上您可以让用户输入一个模式,其中包含
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}]
相反。还请注意,如果执行简单的字符串替换,则需要先将
A
替换为ASCII版本,然后将
N
替换为Unicode变体,以避免在后续结果中替换它

最后,如果要匹配完整的字符串,可能需要在字符串前面加上
^
前缀,并在字符串后面加上
$

C#中的一个示例实现(带有一个微小的优化):

例如,其结果如下:

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中(没有上述优化,因为我不知道如何使用函数作为替换):


生成的正则表达式将稍长一些,因为上面的代码不会对相同的令牌使用重复。

因此,本质上,您可以让用户输入一个模式,其中包含
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}]
相反。还请注意,如果执行简单的字符串替换,则需要先将
A
替换为ASCII版本,然后将
N
替换为Unicode变体,以避免在后续结果中替换它

最后,如果要匹配完整的字符串,可能需要在字符串前面加上
^
前缀,并在字符串后面加上
$

C#中的一个示例实现(带有一个微小的优化):

例如,其结果如下:

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中(没有上述优化,因为我不知道如何使用函数作为替换):



生成的正则表达式将稍长一些,因为上面的代码不会对相同的令牌使用重复。

您能提供具体的示例说明您的目标吗?在我看来,
t
也是数字的,不是吗?无论如何,完全用正则表达式进行的日期验证是不可靠的,至少可以这么说。@MPi-它不必只是一个示例,它不是字母数字的,也不必是字母?
T
将是唯一的字母扫描您提供了具体的示例,说明您的目标是什么?在我看来,
T
也是数字的,不是吗?无论如何,完全用正则表达式进行的日期验证是不可靠的,至少可以这么说。@MPi-它不必只是一个示例,它是字母数字还是只有字母?
T
将只是字母,它会。您需要稍微调整实际代码,但基本思想是一样的。答案中的
s
是什么
string result=Regex.Replace(s,“[^ANT]+”,m=>Regex.Escape(m.Value))请参见编辑。Java代码未经测试,但可能有效。但正如我所说,总的想法是一样的;它只是在语法上看起来略有不同;)这是一个打字错误,应该是
模式
。啊,你可能需要
“\\\\Q$0\\\\E”
来替换。是的,会的。您需要稍微调整实际代码,但基本思想是一样的。答案中的
s
是什么
string result=Regex.Replace(s,“[^ANT]+”,m=>Regex.Escape(m.Value))请参见编辑。Java代码未经测试,但可能有效。但正如我所说,总的想法是一样的;它只是在语法上看起来略有不同;)这是一个打字错误,应该是
模式
。啊,你可能需要
“\\\\Q$0\\\\E”
来替换它。