【问题标题】:Java regex match characters outside Basic Multilingual PlaneJava 正则表达式匹配基本多语言平面之外的字符
【发布时间】:2011-05-01 10:29:34
【问题描述】:

如何从 java 中的 unicode Basic Multilingual Plane 外部匹配字符(目的是删除它们)?

【问题讨论】:

    标签: java regex unicode astral-plane


    【解决方案1】:

    您是在寻找 BMP 之外的特定字符还是所有字符?

    如果是前者,您可以使用StringBuilder 来构造一个包含来自更高平面的代码点的字符串,并且正则表达式将按预期工作:

      String test = new StringBuilder().append("test").appendCodePoint(0x10300).append("test").toString();
      Pattern regex = Pattern.compile(new StringBuilder().appendCodePoint(0x10300).toString());
    
      Matcher matcher = regex.matcher(test);
      matcher.find();
      System.out.println(matcher.start());
    

    如果您要从字符串中删除 所有 个非 BMP 字符,那么我会直接使用 StringBuilder 而不是正则表达式:

      StringBuilder sb = new StringBuilder(test.length());
      for (int ii = 0 ; ii < test.length() ; )
      {
         int codePoint = test.codePointAt(ii);
         if (codePoint > 0xFFFF)
         {
            ii += Character.charCount(codePoint);
         }
         else
         {
            sb.appendCodePoint(codePoint);
            ii++;
         }
      }
    

    【讨论】:

      【解决方案2】:

      要删除所有非 BMP 字符,以下应该有效:

      String sanitizedString = inputString.replaceAll("[^\u0000-\uFFFF]", "");
      

      【讨论】:

      • 你实际测试过这个吗?因为您的字符范围包括用于构造非 BMP 代码点的代理范围。
      • @Anon:正如您在自己的回答中指出的那样,正则表达式是在代码点级别而不是代码单元级别评估的,因此它看不到代理项。
      • 是的,这已经用非 BMP 字符进行了测试。
      • @axtavt - 实际上,我假设正则表达式在字符级别进行评估,并且非 BMP 代码点被简单地转换为代理项。
      • @Anon - 有关 java 中的补充字符的更多信息:java.sun.com/developer/technicalArticles/Intl/Supplementary
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-20
      • 2018-01-22
      • 2014-03-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多