用行终止符除外,用空格替换所有内容

时间:2014-10-03 10:05:11

标签: java regex newline

是否保证以下替换保留行终止符\r\n

"Hello\r\nWorld".replaceAll(".", " ")

我不确定是否可以为所有正则表达式全局指定DOTALL标志。

写这个会更安全吗?

"Hello\r\nWorld".replaceAll("[^\r\n]", " ")

3 个答案:

答案 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部分中有所描述。

可用的标记为iCASE_INSENSITIVE),dUNIX_LINES),mMULTILINE),{{1}来自Java 7的(s),DOTALLu),UNICODE_CASEx),COMMENTSU )。

在关闭所有标记之前,可以为单个UNICODE_CHARACTER_CLASS前面的标记关闭标记,如文档-(?idmsuxU-idmsuxU)中的示例所示。

2 Oracle实现的源代码显示(?idmsux-idmsux:X)c的标志,但它完全没用,因为CANON_EQ是在正则表达式被正确解析之前进行检查和处理(在我看来这是一件坏事,它显然搞得很糟糕,以至于它无法使用)。

设置所有正则表达式的标志

如果您要查找的是一个全局选项,指定在设置选项后编译的所有正则表达式将默认设置某些标志,则答案为,无可用。