我有一个Spring Boot网络应用程序:
在application.properties中,我有这个属性,其值是一个正则表达式:
mytest.regex=^[a-zA-Z0-9()\\-=\\*\\.\\?\\|;,+\\/:&_ \"]*$
我将其注入控制器,如下所示:
@Value("${mytest.regex}")
private String regex;
并在控制器方法中打印,然后使用以下命令编译:
Pattern.compile(regex)
它成功编译,没有任何异常,并在控制台中打印下面的行(注意Java相关的转义字符不是输出):
^[a-zA-Z0-9()\-=\*\.\?\|;,+\/:&_ "]*$
现在,我用application.yml替换application.properties文件。文件内容现在看起来像这样:
mytest:
regex: ^[a-zA-Z0-9()\\-=\\*\\.\\?\\|;,+\\/:&_ \"]*$
请注意,正则表达式完全相同。
控制台输出现在是:
^[a-zA-Z0-9()\\-=\\*\\.\\?\\|;,+\\/:&_ \"]*$
而Pattern.compile(regex)
抛出java.util.regex.PatternSyntaxException: Illegal character range near index 16
现在,我逃离正则表达式中的=
:
^[a-zA-Z0-9()\\-\\=\\*\\.\\?\\|;,+\\/:&_ \"]*$
控制台输出是(注意与属性文件不同,Java相关的转义字符仍然存在):
^[a-zA-Z0-9()\\-\\=\\*\\.\\?\\|;,+\\/:&_ \"]*$
和Pattern.compile(regex)
成功。
现在,请有人解释一下:
=
需要在yml中进行转义,而不是在属性中进行转义好,
我几乎每周五天都在使用正则表达式 - 差不多一年了。
首先,我完全知道open和close括号是正则表达式编译器期望看到转义的控制字符:
^[a-zA-Z0-9\(\)\-=\*\.\?\|;,+\/:&_ "]*$
注意,我在括号前添加了反斜杠。并非所有的正则表达式编译器都是相同的,但我在Java中使用的那个可能希望它们被转义。
其次,Java编译器和Java正则表达式编译器(内置于Java中)也不相同。你需要“转义转义字符”(包括双反斜杠)的唯一原因是因为Java的语言编译器首先编译代码,而Java的(运行时)正则表达式编译器运行第二。
如果正在运行并读取YML文件的正则表达式解析器不是由Java编译器首先编译的,那么您就不需要双重转义(转义转义符 - a.k.a。'反斜杠')。相反,只在表达式中使用一个反斜杠字符。