【问题标题】:Regex for string splitting not working properly用于字符串拆分的正则表达式无法正常工作
【发布时间】:2016-03-16 08:16:37
【问题描述】:

我想将一个字符串拆分为 2 个字符,不带任何分隔符,但 Regex 拆分无法正常工作

这是我的代码:-

  String str="splitstring";
    System.out.println("Split.."+str.trim().split("(?<=\\G.{2})").length);
    System.out.println("Split.."+str.trim().split("(?<=\\G.{2})")[0]);
    System.out.println("Split.."+str.trim().split("(?<=\\G.{2})")[1]);

输出:-

 Split..2

 Split..sp

 Split..litstring

【问题讨论】:

  • 你的预期输出是什么?
  • 我的预期输出是具有 2 个字符的拆分字符串数组,并且在每个位置 2 个字符可用 like.on 位置 0 它将返回“sp”而不是位置 1 返回“li”而不是 2 位置“ ts" 直到字符串结尾
  • 这一定是 ICU 正则表达式库中的故障。
  • @WiktorStribiżew 我认为这是一个错误确实是正确的,因为以下System.out.println(Arrays.toString(str.split("(?&lt;=\\G.{2})"))); 给出了预期的行为..
  • @KevinCruijssen:我开始认为lookbehind 中的\G 行为是未定义的。这是PHP demo ([0] =&gt; sp, [1] =&gt; lit, [2] =&gt; str, [3] =&gt; ing, [4] =&gt; )、C# demo(与 Java 输出相同)、Ruby demo(与 Java 输出相同)。 R (that also uses a PCRE engine!) example works as in Java, too.

标签: java android regex split


【解决方案1】:

看起来这是您的 Java 环境中结果阈值限制的错误。尝试通过明确提供限制来解决它:

    String str="splitstring";
    int partsCount = (str.length() + 1) / 2;
    System.out.println("Split.."+str.trim().split("(?<=\\G.{2})", partsCount).length);
    System.out.println("Split.."+str.trim().split("(?<=\\G.{2})", partsCount)[0]);
    System.out.println("Split.."+str.trim().split("(?<=\\G.{2})", partsCount)[1]);

【讨论】:

    【解决方案2】:

    我假设您想将字符串分成两个相等的部分,子字符串。那么这可能会有所帮助!

    System.out.println("Split.."+str.trim().split("(?=\\D)")[0]);
    

    【讨论】:

      【解决方案3】:

      你为什么要为此使用正则表达式?

      你可以这样做:

      String str = "splitstring";
      System.out.println("String-length: " + str.length());
      for (int i = 0; i < str.length(); i += 2) { // Increments of 2
        System.out.print("Split.." + str.charAt(i));
        if (i != str.length() - 1) {
          System.out.print(str.charAt(i + 1));
        }
        System.out.println();
      }
      

      输出:

      String-length: 11
      Split..sp
      Split..li
      Split..ts
      Split..tr
      Split..in
      Split..g
      

      编辑:如果你坚持使用正则表达式,这里是:

      final String str = "splitstring";
      System.out.println(Arrays.toString(
          str.split("(?<=\\G.{2})")
      ));
      

      输出与上面相同。似乎确实存在错误或其他问题,因为正则表达式与您的问题相同。但不能确定,因为这不是我的专业知识。


      编辑 2:Jon Skeet has an alternative method that is more efficient than mine above

      嗯,通过蛮力很容易做到这一点:

      public static List<String> splitEqually(String text, int size) {
          // Give the list the right capacity to start with. You could use an array
          // instead if you wanted.
          List<String> ret = new ArrayList<String>((text.length() + size - 1) / size);
      
          for (int start = 0; start < text.length(); start += size) {
              ret.add(text.substring(start, Math.min(text.length(), start + size)));
          }
          return ret;
      }
      

      我认为为此使用正则表达式真的不值得。

      编辑:我不使用正则表达式的理由:

      • 这不使用任何正则表达式的真正模式匹配。它只是在计数。
      • 怀疑上面的方法会更有效率,虽然在大多数情况下它并不重要
      • 如果您需要在不同的地方使用可变大小,您可以使用重复或辅助函数来构建正则表达式本身 一个参数 - ick。
      • 另一个答案中提供的正则表达式首先没有编译(无效转义),然后没有工作。我的代码第一次工作。那是 更多地证明了正则表达式与纯代码的可用性,IMO。

      【讨论】:

      • 你为什么要为此使用正则表达式? - 比较你必须编写多少行代码。使用正则表达式,它是单行的。
      • @WiktorStribiżew 可以,但这可以放在方法中并隐藏在看不见的某个地方。就我个人而言,我认为人们倾向于过早地使用正则表达式,而很多时候它可以完美地完成。无论如何,我已经进行了编辑以使用正则表达式获得相同的结果..
      • 有些人认为放入一个方法并隐藏在某个看不见的地方是一种优势。顺便说一句,您建议的正则表达式解决方案不适用于 Android 上的 OP。请注意,Android 使用 ICU 正则表达式库,与 Java 中使用的不同。
      猜你喜欢
      • 1970-01-01
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多