正则表达式匹配URL末尾的"/"字符或行尾

96

我有一个URL,想要使用正则表达式来匹配并提取一些组。我的问题在于URL可以以“/”结尾,也可以继续带上更多的URL文本。我想匹配如下的URL:

但不匹配这样的内容:

因此,我认为最好的方式是:

/(.+)/(\d{4}-\d{2}-\d{2})-(\d+)[/$]

在结尾处的字符类包含“/”或行尾。不过,字符类似乎对其中的“$”不满意。我该如何最好地区分这些URL,同时仍然获取正确的组?

4个回答

137

要匹配内容的开头或结尾,可以使用(^|\|z)

这仅适用于您不使用多行匹配(即您正在匹配单个URL而不是以换行符分隔的URL列表)的情况。


将其与您拥有的更新版本组合在一起:

/(\S+?)/(\d{4}-\d{2}-\d{2})-(\d+)(/|\z)
请注意,我已将起始位置更改为非贪婪匹配非空格字符( \S+? ),而不是匹配任何内容( .* )。

7
如何赠送您更多的积分?谢谢这个。 "/|\A" 可以匹配正斜杠或字符串的开头,这是用于记录的。 - Senica Gonzalez
3
注意:JavaScript 不支持 \Z\z - Seybsen

69
您现在已经有了几个正则表达式,可以实现您想要的功能,所以这已经足够了。但是为什么您的尝试不起作用还没有被提到:在字符类内,`$`(以及`^`、`.`和`/`)没有特殊含义,因此`[/$]`匹配一个字面上的`/`或字面上的`$`而不是终止正则表达式(`/`)或匹配行尾(`$`)。

8
这是正则表达式文档中经常被忽略并且没有足够提及的内容。 - Steve Dunn
6
请注意,在字符类中,“^”可能具有特殊含义。如果它是类中的第一个字符,它将创建一个负类,匹配除其他字符以外的任何内容。例如,要匹配除“a”或“b”之外的任何内容,可以使用[^ab]。如果要包括字面上的“^”,请确保它不是第一个字符,所以要匹配“a”、“b”或“^”,您将使用[ab^]。 - David Mason

50
/(.+)/(\d{4}-\d{2}-\d{2})-(\d+)(/.*)?$

第一捕获组 (.+)

.+ 匹配除行终止符之外的任何字符

  • + 量词 — 匹配至少一次,至多不限,尽可能多地回溯 (贪婪匹配)

第二捕获组 (\d{4}-\d{2}-\d{2})

\d{4} 匹配数字(等价于 [0-9]

  • {4} 量词 — 恰好匹配 4

- 匹配连字符字符 - 字面上(区分大小写)

\d{2} 匹配数字(等价于 [0-9]

  • {2} 量词 — 恰好匹配 2

- 匹配连字符字符 - 字面上(区分大小写)

- 匹配连字符字符 - 字面上(区分大小写)

第三捕获组 (\d+)

\d+ 匹配数字(等价于 [0-9]

  • + 量词 — 匹配至少一次,至多不限,尽可能多地回溯 (贪婪匹配)

第四捕获组 (.*)?

? 量词 — 匹配零次或一次,尽可能多地回溯 (非贪婪匹配)

.* 匹配除行终止符之外的任何字符

  • * 量词 — 匹配至少零次,至多不限,尽可能多地回溯 (贪婪匹配)

$ 断言字符串末尾的位置


为什么最后一个 / 不需要转义? - Peter Mortensen

23

在 Ruby 和 Bash 中,您可以在括号内使用 $

/(\S+?)/(\d{4}-\d{2}-\d{2})-(\d+)(/|$)

这种解决方案与Pete Boughton的类似,但保留了$的使用,它表示行末,而不是使用\z,它表示字符串末尾。


2
从我所知,PHP也是如此。实际上,我看不出为什么$不能在括号()中使用。只有方括号[]才会使其成为文字意义。 - Joel Mellon
5
在 JavaScript 中,$ 符号可以这样使用,但是\z不能(适用于 Chrome 48、Firefox 43 和 IE9)。 - Vsevolod Golovanov
1
这是最直接的选项。匹配斜杠或行尾。它甚至匹配了这个问题的标题! - Brett Donald

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接