代码之家  ›  专栏  ›  技术社区  ›  Fabian Röling Dan Williams

为什么“;”和“\\;”找到相同的?

  •  0
  • Fabian Röling Dan Williams  · 技术社区  · 6 年前

    我刚刚找到像这样的Java代码:

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

    它返回:

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

    string.split确实使用regex,但从我的研究中我发现 ; 不是regex中的特殊字符,不必转义。所以我试着用:

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

    它还是一样的!那这里发生了什么?Java是不是很好,忽略了正则表达式中的一个无用的反斜杠?但我也用记事本++试过了,在那里它也找到了一个Semikolon。

    3 回复  |  直到 6 年前
        1
  •  2
  •   Andy Turner    6 年前

    the Javadoc of Pattern (强调我的):

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

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

        2
  •  3
  •   Tim Biegeleisen    6 年前

    在以下代码中:

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

    String#split() 在正则表达式上下文中执行。两个反斜杠 \\ 结果是一个字面反斜杠,所以您最终将 \; ,在功能上与 ; ,因为分号不需要转义。

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

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

    在regex术语中,这将对应于按文本拆分 ; . 因为分隔符不会出现在字符串中,所以您只会得到一个数组,它的第一个元素就是输入字符串。

    请参阅@andyturner的答案,以获取有关为什么拆分 ; 首先是允许的。

        3
  •  0
  •   wp78de    6 年前

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

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

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

    所以,如果你愿意 引用 要指定您的模式,不会发生如下代码示例所示的拆分:

    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
    

    否则,它只是在 split 方法由Tim和Andy解释。