是否保证以下替换保留行终止符\r\n
?
"Hello\r\nWorld".replaceAll(".", " ")
我不确定是否可以为所有正则表达式全局指定DOTALL
标志。
写这个会更安全吗?
"Hello\r\nWorld".replaceAll("[^\r\n]", " ")
答案 0 :(得分:0)
如the Pattern
Javadocs中所述:
正则表达式
.
匹配除行终止符之外的任何字符,除非指定了DOTALL
标志。
因此,如果您只使用第一个表达式,它将按您的意愿工作:
"Hello\r\nWorld".replaceAll(".", " ")
答案 1 :(得分:0)
如果查看String.replaceAll()的实现,它会在内部使用Pattern而不使用DOTALL标志,而不引用任何全局设置。
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
Pattern.compile(regex)将0(无标志)传递给Pattern.compile(正则表达式,标志),这将禁用DOTALL模式。
public static Pattern compile(String regex) {
return new Pattern(regex, 0);
}
Pattern可用于手动添加DOTALL标志但默认不使用它,这会更改Pattern的单个实例的行为
一个有效的例子:
String test = "Hello\r\nWorld";
System.out.println(String.format("With DOTALL >%s<",
Pattern.compile(".", Pattern.DOTALL).matcher(test).replaceAll(" ")));
System.out.println(String.format("Without DOTALL >%s<",
Pattern.compile(".").matcher(test).replaceAll(" ")));
输出
With DOTALL > <
Without DOTALL >
<
答案 2 :(得分:0)
.
和行分隔符由于.
将\r
和\n
视为行分隔符(\r
,\n
,\r\n
1 ,\u0085
,\u2028
,\u2029
),行分隔符序列\r\n
或任何涉及\r
或\n
的序列自然不匹配.
。
1 关于\r\n
行终止符序列,当涉及$
时会发现更有趣的行为,因为引擎需要将\r\n
视为回溯时的原子线分隔符。
您可以为整个正则表达式指定任何标志(CANON_EQ
2 除外),或者甚至是正则表达式的一部分,(?<flags>)
前一种情况,(?<flags>:<re>)
适用于后一种情况。这在Pattern
课程文档的Special constructs部分中有所描述。
可用的标记为i
(CASE_INSENSITIVE
),d
(UNIX_LINES
),m
(MULTILINE
),{{1}来自Java 7的(s
),DOTALL
(u
),UNICODE_CASE
(x
),COMMENTS
(U
)。
在关闭所有标记之前,可以为单个UNICODE_CHARACTER_CLASS
前面的标记关闭标记,如文档-
和(?idmsuxU-idmsuxU)
中的示例所示。
2 Oracle实现的源代码显示(?idmsux-idmsux:X)
是c
的标志,但它完全没用,因为CANON_EQ
是在正则表达式被正确解析之前进行检查和处理(在我看来这是一件坏事,它显然搞得很糟糕,以至于它无法使用)。
如果您要查找的是一个全局选项,指定在设置选项后编译的所有正则表达式将默认设置某些标志,则答案为否,无可用。