【问题标题】:regex for multiple group not working - Java 1.7 to 1.8 - ScriptEngine Rhino to Nashorn多组的正则表达式不起作用 - Java 1.7 到 1.8 - ScriptEngine Rhino 到 Nashorn
【发布时间】:2017-09-06 13:32:32
【问题描述】:

我遇到了question 中所述的正则表达式问题

字符串如下:<SPAN>06-24-2015 11:28AM 0250 01 90775 05342</SPAN>

1.7 Java 上的 JS 代码运行良好: 正则表达式:

/<span>(\\d{2}-\\d{2}-\\d{4})\\s*?(\\d{1,2}:\\d{2}\\s*?(?:am|pm))\\s*?(?:<\\/SPAN><BR\\/?><SPAN>)?\\s*?((\\d[ -]*?){13,17})\\s*?<\\/span>/i

但是正如上面共享的问题中所描述的那样,在 1.8 Java 中同样不起作用。 得到该问题的建议后,我逐组创建了我的正则表达式,并知道只有正则表达式的最后一部分在 1.8 中不起作用。

ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngine engine = mgr.getEngineByName("JavaScript");

        String js = "var fileSrc = '<SPAN>06-24-2015  11:28AM  0250 01 90775 05342</SPAN>';"
                + "var trans_regex = /<span>(\\d{2}-\\d{2}-\\d{4})\\s*?(\\d{1,2}:\\d{2}\\s*?(?:am|pm))\\s*?(?:<\\/SPAN><BR\\/?><SPAN>)?\\s*?((\\d[ -]*?){13,17})\\s*?/i;"
                + "print('executed regex result : ' + trans_regex.exec(fileSrc) ) ; ";

        Object result = engine.eval(js);

在上面共享的代码中,正则表达式被截断为:

/<span>(\\d{2}-\\d{2}-\\d{4})\\s*?(\\d{1,2}:\\d{2}\\s*?(?:am|pm))\\s*?(?:<\\/SPAN><BR\\/?><SPAN>)?\\s*?((\\d[ -]*?){13,17})\\s*?/i

结果为:

executed regex result : <SPAN>06-24-2015  11:28AM  0250 01 90775,06-24-2015,11:28AM,0250 01 90775,5

而实际的正则表达式是:

/<span>(\\d{2}-\\d{2}-\\d{4})\\s*?(\\d{1,2}:\\d{2}\\s*?(?:am|pm))\\s*?(?:<\\/SPAN><BR\\/?><SPAN>)?\\s*?((\\d[ -]*?){13,17})\\s*?<\\/span>/i

任何人都可以建议应该做些什么来使实际的正则表达式在 1.8 上再次工作。

实际的 JS 正则表达式可以在这里找到https://regex101.com/r/ARqNJ4/1

编辑

在 1.7 中,脚本引擎是 Rhino,在 1.8 中是 Nashorn

编辑 2

根据评论中的建议,截断的错误正则表达式如下:

要匹配的字符串 :&lt;SPAN&gt;0250 01 90775 05342&lt;/SPAN&gt;

目前使用的正则表达式:

/<span>\\s*?((\\d[ -]*?){13,17})\\s*?/i

输出(不是必需的):

executed regex result : <SPAN>0250 01 90775,0250 01 90775,5

正则表达式在 1.7 中工作:

/<span>\\s*?((\\d[ -]*?){13,17})\\s*?<\\/span>/i

【问题讨论】:

  • 记住 JavaScript 和 Java 是不同的。一种语言的功能不一定存在于另一种语言中。
  • @evolutionxbox,我同意。但是代码在 1.7 中运行良好。所以,我正在寻找关于我的正则表达式最后一组不起作用的任何指针。可能是任何解决方法!跨度>
  • 我会检查 Java 1.8 的更新日志,因为听起来好像发生了一些变化。
  • @evolutionxbox 在 1.8 中有一个新的 JS 引擎,Nashorn
  • 是否有一大块正则表达式(靠近前面)可以更改为.* 并仍然显示问题?它使潜在的回答者更加关注在哪里寻找。或者删除一块工作正常的正则表达式,并删除输入字符串的相应部分。

标签: javascript java regex


【解决方案1】:

据我所知,您需要做的就是在结束 &lt;\\/span\\&gt; 之前添加 [^&lt;]*? 。此外,您不需要转义最后一个跨度的起始 &lt;。所以,这就是这个脚本:

    ScriptEngineManager mgr = new ScriptEngineManager();
    ScriptEngine engine = mgr.getEngineByName("JavaScript");
    String js = "var fileSrc = '<SPAN>06-24-2015  11:28AM  0250 01 90775 05342</SPAN>';"
            + "var trans_regex = /\\<span\\>(\\d{2}-\\d{2}-\\d{4})\\s*?(\\d{1,2}:\\d{2}\\s*?(?:am|pm))\\s*?(?:<\\/SPAN><BR\\/?><SPAN>)?\\s*?((\\d[ -]*?){13,17})\\s*?[^<]*?\\<\\/span\\>/i ;"
            + "print('executed regex result : ' + trans_regex.exec(fileSrc) ) ; "
            + "var t_time = trans_regex.exec(fileSrc)[2];"
            + "var t_cc = trans_regex.exec(fileSrc)[3];"
            + "print(\" time \" + t_time)";

    Object result = engine.eval(js);

结果:

executed regex result : <SPAN>06-24-2015  11:28AM  0250 01 90775 05342</SPAN>,06-24-2015,11:28AM,0250 01 90775,5
 time 11:28AM

更新 - 解释和替代方案

这是原始正则表达式的最后一组:((\\d[ -]*?){13,17})。这对我来说看起来很棘手,但是,我不知道这背后的意图。它的作用:

  1. 匹配一个数字
  2. 匹配零个或多个空格或连字符
  3. 重复第 1 步和第 2 步,至少 13 次,最多 17 次。

这真的很棘手,因为零个或多个空格或连字符可以匹配任何地方。我相信意图是这样的:

考虑字符串0250 01。前导 '0' 将匹配 1 个数字和 0 个其他字符。 '2''5' 也是如此。然后,'0 ' 将匹配一个数字和一个空格。以此类推,最多 13-17 位。

显然,Nashorn 引擎无法处理此构造。如果我添加这个打印语句:

+ "print (trans_regex.exec(fileSrc));"

那么我会得到这个结果:

<SPAN>06-24-2015  11:28AM  0250 01 90775 05342</SPAN>,06-24-2015,11:28AM,0250 01 90775,5

这告诉我 ((\\d[ -]*?){13,17}) 匹配 0250 01 90775,这只有 11 位数字。所以我的“修复”只是在结束 &lt;\span&gt; 的开头捕捉到其余字符。

根据this regex demo,你的逻辑应该匹配。

解决方法 1

您可以使连字符或空格部分变得贪婪。 IE。删除*之后的?

((\\d[ -]*){13,17})

我会选择这个。

解决方法 2

您可以指定更多的重复次数,在本例中为 19:

((\\d[ -]*?){13,19})

恐怕在这种情况下,您也必须更改下限。

【讨论】:

  • 你能解释一下你的答案吗
  • 这只是反复试验。添加[^&lt;]*? 将使正则表达式匹配。它消耗不是&lt; 字符的每个字符。一旦你有一个匹配,`trans_regex.exec(fileSrc)` 给出一个包含组的数组,就是这样。我会尽快更新答案并提供更多详细信息。
  • 解决方法 1 中的贪婪是什么意思,总体解释很好
  • @softxide greedy 表示尽可能匹配。 IE。 .*h 将匹配到最后一个 'h' 的所有内容。另一方面,非贪婪的.*?h 将匹配第一个'h'。在您的情况下,这种区别只会影响性能,因为您使用了非常精确的字符类。
猜你喜欢
  • 1970-01-01
  • 2015-07-14
  • 1970-01-01
  • 2015-06-19
  • 2016-11-22
  • 2016-09-28
  • 2012-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多