javascript - RegExp 适用于 JS 和 PHP,但不适用于 Java

标签 javascript java php regex

我有一个正则表达式来从 HTML 源代码中提取 id 和标签。可以查到HERE .

正如你所看到的,它工作得很好而且速度很快,但是当我用相同的源代码在java中尝试这个正则表达式时,它1.永远使用并且2.只匹配一个字符串(从第一个a 到最后一个 a 是一个匹配)。

我尝试使用 Multiline 标志打开和关闭,但没有区别。我不明白正则表达式如何在除了java之外的任何地方工作。有什么想法吗?

private static final String COURSE_REGEX = "<a class=\"list-group-item list-group-item-action \" href=\"https:\\/\\/moodle-hs-ulm\\.de\\/course\\/view\\.php\\?id=([0-9]*)\"(?:.*\\s){7}<span class=\"media-body \">([^<]*)<\\/span>";

Pattern pattern = Pattern.compile(COURSE_REGEX, Pattern.MULTILINE);
Matcher matcher = pattern.matcher(sourceCode);
List<String> courses = new ArrayList<>();

while(matcher.find() && matcher.groupCount() == 2){
    courses.add(matcher.group(1) + "(" + matcher.group(2) + ")");
}

最佳答案

您的正则表达式遇到 catastrophic backtracking由于可能的排列数量庞大,子表达式 (?:.*\s){7}需要检查(因为 . 也可以匹配空格)。 Java 在一定数量的步骤后中止匹配尝试(不确定有多少,当然> 1.000.000)。 PHP或者JS可能没那么谨慎。

如果您将正则表达式的该部分简化为 .*? ,您确实得到了匹配项:

"(?s)<a class=\"list-group-item list-group-item-action \" href=\"https://moodle-hs-ulm\\.de/course/view\\.php\\?id=([0-9]*)\".*?<span class=\"media-body \">([^<]*)</span>"

请注意,您需要 DOTALL标志( (?s) ,因此 . 可能匹配换行符)而不是 MULTILINE改变 ^ 行为的标志和$ anchor (您的正则表达式没有使用这些 anchor )。

另请注意,您不需要在 Java 正则表达式中转义斜杠。

这个解决方案不是很稳健,因为 .*?是相当不具体的。我想你之前尝试过 (?:.*\\s){7}可能被设计为匹配不超过 7 行的文本?在这种情况下,您可以使用 (?:(?!</a>).)*而是确保您不会进入下一个 <a>标签。这是使用正则表达式解析 HTML 的危险之一:)

最后,来自贵校信息学系工作人员的问候:)

关于javascript - RegExp 适用于 JS 和 PHP,但不适用于 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54305864/

相关文章:

javascript - 图例与 map 上的颜色不对应。融合表

javascript - 本地存储 - 保存使用 JavaScript 完成的 DOM 更改

java - 根据 pom 中的 Activity 配置文件更改包装

java - 为什么在我尝试关闭它们后我的线程仍然处于 Activity 状态?

PHP 使用 XML 的最佳方法是什么?需要创建和解析 XML 响应

javascript - Chrome Cordova 应用插件访问

javascript - 使用 CSS 的无过渡关键帧

java - 是否有一个程序可以告诉您正在调用哪个类/方法

javascript - 使用 jquery 在我的站点中加载其他网页不起作用

php - 单击“返回”时,客户的 CC 双倍收费