为什么&#34 ;;"和" \\;"找到相同的?

时间:2018-05-31 11:14:32

标签: java regex escaping

我刚刚发现了这样的Java代码:

"bla;bla;bla".split("\\;");

它返回:

["bla","bla","bla"]   // String array of course

String.split确实使用正则表达式,但是根据我的研究,我发现;不是正则表达式中的特殊字符,并且不必转义。所以我尝试将其替换为:

"bla;bla;bla;".split(";");

它仍然是一样的!那么这里发生了什么? Java试图变得更好并忽略正则表达式中无用的反斜杠吗?但我也用Notepad ++尝试过它,并且它也都找到了一个semikolon。

3 个答案:

答案 0 :(得分:3)

在以下代码中:

"bla;bla;bla".split("\\;");

String#split()在正则表达式上下文中执行。两个反斜杠\\会产生文字反斜杠,因此您最终会在\;上进行拆分,这在功能上与在;上拆分相同,因为分号不需要转义。

如果您尝试了以下拆分,则不会得到您期望的结果:

"bla;bla;bla".split("\\\\;");

在正则表达式中,这将与文字\;分开。由于该分隔符永远不会出现在您的字符串中,您只需获得一个数组,其第一个元素是该输入字符串。

请参阅@AndyTurner的答案,了解为何首先允许拆分\;

答案 1 :(得分:2)

来自the Javadoc of Pattern(强调我的):

  

反斜杠字符('\')用于引入转义构造

     

...

     

在任何不表示转义构造的字母字符之前使用反斜杠是错误的;这些保留用于将来对正则表达式语言的扩展。 可以在非字母字符之前使用反斜杠,无论该字符是否为非转义构造的一部分。

答案 2 :(得分:0)

答案很好。但是,没有人提到Pattern.quote()

Java没有原始字符串或文字字符串(例如C#中的@"...";逐字字符串或Python中的r"..."原始字符串)。尽管如此,对于正则表达式,我们使用quote方法返回指定String的文字模式String:

  

此方法生成一个可用于创建Pattern的String   这将匹配字符串s,就好像它是一个文字模式。

因此,如果您使用quote指定模式,则不会发生拆分,如以下代码示例所示:

import java.util.regex.Pattern;
class Example
{
  public static void main (String[] args) throws java.lang.Exception
  {
  String sourcestring = "bla;bla;bla";
  Pattern re = Pattern.compile(Pattern.quote("\\;"));
  String[] parts = re.split(sourcestring);
    for(int partsIdx = 0; partsIdx < parts.length; partsIdx++ ){
      System.out.println( "[" + partsIdx + "] = " + parts[partsIdx]);
    }
  }
}

输出:

[0] = bla;bla;bla

否则,它只是在Tim和Andy所解释的split方法的正则表达式上下文中的一个转义分号。