【问题标题】:Regex Return Number between last / and?最后 / 和之间的正则表达式返回数?
【发布时间】:2016-04-11 14:31:09
【问题描述】:

我正在尝试在最后一个 / 和第一个 ? 之间的 URL 末尾选择 ID 例如:http://www.website.com/page/support/28685875?JK.kj_id=

将仅提取 id:28685875

我在正则表达式方面非常糟糕,并且已经弄清楚了这些

  • ([^/]+$)选择结尾28685875?JK.kj_id=

  • .+?(?=\?)选择开始www.website.com/page/support/28685875

我想尝试以各种方式将它们组合在一起,但几个小时后我没有成功。

谁能解释我做错了什么/如何选择这个 URL 部分?

编辑:我正在使用基于 Java 的 ETL 应用程序来转换数据集。

【问题讨论】:

  • 来自正则表达式标签信息:“由于正则表达式尚未完全标准化,所有带有此标签的问题也应包含一个指定适用的编程语言或工具的标签。”
  • 在谈到用 Java 解析 URL 时,我建议使用 URL class。除非有更严格的要求,否则这似乎是最干净的解决方案。

标签: java regex


【解决方案1】:

非正则表达式解决方案

在 Java 中,您可以使用 URL class 来解析 URL。因此,最好的解决方案是:

URL aURL = new URL("http://www.website.com/page/support/28685875?JK.kj_id=");
String str = aURL.getPath().substring(aURL.getPath().lastIndexOf("/") + 1);
System.out.println(str);

demo

参见Parsing a URL 教程。

正则表达式解决方案

您要查找的正则表达式应匹配最后一个/,后跟数字或直到? 的任何符号,可能还跟/ 以外的可选字符到字符串末尾。 /? 之间的部分可以捕获到一个组中然后使用。

\/([^\/]*)\?[^\/]*$

regex demo

否定字符类[^\/] 匹配除/ 之外的任何字符。第 1 组将保存您需要的值。

匹配您需要使用环视的子字符串:

(?<=/)[^/]*(?=[?][^/]*$)
^^^^^      ^^^

或更简单的:

(?<=/)[^/?]+(?=[?]|$)

demo

Java code:

String s = "http://w...content-available-to-author-only...e.com/page/support/28685875?JK.kj_id=";
Pattern pattern = Pattern.compile("(?<=/)[^/?]+(?=[?]|$)");
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
    System.out.println(matcher.group()); 
} 

但是,您可以使用基于捕获的正则表达式并使用 matcher.group(1) 访问组 1。

(?&lt;=/)([^/?]+)(?=[?]|$) 模式执行以下操作:

  • (?&lt;=/) - 检查字符串中当前测试位置之前是否有/(如果失败,则索引前进,测试下一个位置)
  • [^/?]+ - 匹配除 /? 之外的 1 个或多个字符(此处无需转义)
  • (?=[?]|$) - 检查下一个字符是 ? 还是字符串结尾。如果不是,则比赛失败。

【讨论】:

  • 根据您使用的平台/工具/语言,正确的解决方案可能不是正则表达式。仅当您必须使用正则表达式时才使用它。
  • 我添加了一个基于环视的解决方案
  • 感谢您的详细回答,在我最后几个小时的 elarnign 正则表达式中,我对这些 ?
  • 您对寻找其他工具进行 URL 解析是正确的。但大多数时候我更喜欢正则表达式而不是字符串解析:您可以分离实现和上下文(甚至可以在配置文件中给出模式),可以在不需要实现的情况下测试正则表达式,并且正则表达式上的异常更可预测而不是字符串解析的异常(如果输入中没有“/”会发生什么?如果“/”是最后一个字符会发生什么?)
  • @AutomatedChaos:许多 SO 用户认为,如果没有它也可以完成工作,则不应使用正则表达式。在这里,要求是获取最后一个/ 之后的子字符串,直到它之后的第一个?(如果有)。因此,如果/ 位于末尾,则结果将是an empty string,正如预期的那样。如果没有/,还有一个empty string get returned since the path is empty(所以,它会原样返回整个字符串,因为lastIndexOf会返回-1,然后我们将+1相加,并得到0索引作为起点substring)。这可以安全使用。
【解决方案2】:

试试这个:

\/([^\/\?]+)(?:\?|$)

这将获取最后一个“/”之后和“?”之前的任何字符,如果是“?”存在。在这里,第一组将为您提供 ID。

简化

(?<=\/)([^\/\?]+)(?=\?|$)

这将在不分组的情况下获取 ID。

【讨论】:

  • 我认为它也应该有效。请注意,? 不必在字符类中转义。
  • 我不认为 url 有多个“?” .如果我错了,请纠正我?
  • 好吧,正如我所说,在这种情况下它也应该可以工作。至于?,一个URL中可以有多个,见Is it valid to have more than one question mark in a URL?
  • 这似乎非常有效。谢谢,我现在可以安心入睡,4 小时后醒来工作。一个后续问题:我如何修改它以排除 / 和 ?从最终结果来看?
  • 无法理解后续问题。请解释一下?
猜你喜欢
  • 2011-06-21
  • 2019-03-06
  • 1970-01-01
  • 2016-11-18
  • 2012-02-22
  • 2023-04-07
  • 1970-01-01
相关资源
最近更新 更多