以下是造成混乱的代码:
String s = "onentwonthreen";
s = s.replaceAll("^", "START");
s = s.replaceAll("$", "END");
System.out.print(s);
这是输出:
STARTone
two
threeEND
END
我知道在Java中,美元符号与行尾匹配,但我认为即使字符串以\n结尾,它也会起到相同的作用。为什么"END"被打印了两次?
Java Regex默认情况下将输入视为单行
参考线路终端部分
默认情况下,正则表达式^和$忽略行终止符,分别只在整个输入序列的开头和结尾匹配。如果MULTILINE模式被激活,则^在输入开始时和除输入结束时以外的任何行终止符之后匹配。在MULTILINE模式下,$正好在行终止符或输入序列的末尾之前匹配。
由于我们没有启用MULTILINE
模式,因此在这种情况下,只应匹配输入结束,而不应匹配n
。所以这可能是RotoRa提到的一个bug。
关于这个错误的一个可能的提示可能来自Pattern#Dollar的注释,它是处理$
的内部类
当不处于多行模式时,$只能在最后匹配输入的,除非输入终止于其中它正好在最后一行终止符之前匹配。
"onentwonthreen"
和n
在"
满足情况unless the input ends in a line terminator in which it matches right before the last line terminator
之前
要匹配的解决方案\n
如果要正确匹配n
和$
,可以使用类似s = s.replaceAll("(?m)^", "START").replaceAll("(?m)$", "END");
的标志表达式(?m(启用MULTILINE模式。你会看到
STARToneEND
STARTtwoEND
STARTthreeEND
END
这次。请注意,由于输入序列的末尾也匹配,因此末尾中仍有两个END
。