【问题标题】:Java regex lookbehind is not working as js regex lookbehindJava regex lookbehind 不能作为 js regex lookbehind 工作
【发布时间】:2020-07-24 20:42:45
【问题描述】:

我有这个目标:

给定字符串:"Part1-part2-part3-part4-part5"
在第二次出现'-'时拆分它,
所以我期待一个数组[ "Part1-part2", "part3-part4-part5" ]

我做了什么:

"Part1-part2-part3-part4-part5".split("(?<=^\\w+-\\w+)-"

但是 jdk 8 上的结果:
它没有找到第二个'-'的匹配,并返回整个字符串
证据:https://ideone.com/myWppm

但是,当我尝试在线正则表达式处理网站和 node.js(或 chrome)[相信我,现代 js 支持lookbehind]时,结果符合预期
证据:https://ideone.com/ttQWNr

我现在正在使用的黑客(不符合成为解决方案的条件):

使用前瞻而不是后瞻,从末尾第三次出现“-”
"Part1-part2-part3-part4-part5".split("-(?=\\w+-\\w+-\\w+$)");

【问题讨论】:

    标签: java regex regex-lookarounds lookbehind


    【解决方案1】:

    Java 确实支持使用量词的有限后视,例如 {0,100}

    要匹配除连字符以外的任何字符,您可以使用[^-],即negated character class

    如果要排除匹配的换行符,可以将其扩展为 [^-\\r\\n]

    你可能会使用:

    (?<=^[^-]{0,100}-[^-]{0,100})-
    

    部分

    • (?&lt;= 正向向后看,断言左边是
      • ^ 字符串开始
      • [^-]{0,100}- 匹配除 - 之外的任何字符 0 - 100 次,然后匹配第一个 -
      • [^-]{0,100} Match 0 - 100 times any char except-`
    • ) 近距离观察
    • - 匹配第二个 - 进行拆分

    Regex demo | Java demo

    例如

    System.out.println(
        Arrays.toString(
            "Part1-part2-part3-part4-part5".split("(?<=^[^-]{0,100}-[^-]{0,100})-")
        )
    );
    

    输出

    [Part1-part2, part3-part4-part5]
    

    【讨论】:

      【解决方案2】:

      Java 不支持可变宽度的lookbehinds。假设您的输入字符串将 always 有五个连字符分隔的术语,我们可以通过在拆分之前检查前面是否有两个连字符来代替拆分逻辑:

      String input = "Part1-part2-part3-part4-part5";
      String[] parts = input.split("-(?=[^-]+-[^-]+-[^-]+$)");
      System.out.println(Arrays.toString(parts));
      

      打印出来:

      [Part1-part2, part3-part4-part5]
      

      【讨论】:

      • 嘿,我必须将此正则表达式传递给一些使用 spark-sql 的 split 函数作为底层代码的代码。我没有传递一些 lambda / 自定义函数对象的选项,因为它就像 apache spark 的黑盒,并且无法优化操作。因此,作为解决方案,我只需要一个正则表达式。要了解一些想法,请在此处查看:sparkbyexamples.com/spark/…
      • 我给了你一个正则表达式。我不明白你的评论。
      【解决方案3】:

      不要使用split(),而是使用匹配:

      String input = "Part1-part2-part3-part4-part5";
      String regex = "(\\w+-\\w+)-(.*)"
      String[] result; // just to simulate result of split()
      Matcher m = Pattern.compile(regex).matcher(input);
      if (m.matches()) {
          result = new String[] { m.group(1), m.group(2) };
      } else {
          result = new String[] { input };
      }
      

      当然它的代码有点多,但是您可以轻松地增强正则表达式以执行更多验证,例如除了-(显然还有_)之外没有特殊字符,即使是第二个破折号之后的文本。

      【讨论】:

      • 嘿,我必须将此正则表达式传递给一些使用 spark-sql 的 split 函数作为底层代码的代码。我没有传递一些 lambda / 自定义函数对象的选项,因为它就像 apache spark 的黑盒,并且无法优化操作。因此,作为解决方案,我只需要一个正则表达式。要了解一些想法,请在此处查看:sparkbyexamples.com/spark/…
      猜你喜欢
      • 1970-01-01
      • 2020-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-14
      相关资源
      最近更新 更多