我正在尝试编写一个正则表达式来匹配这些URL中的数字(12345678
和1234567890
)。
http://www.example.com/p/12345678
http://www.example.com/p/12345678?foo=bar
http://www.example.com/p/some-text-123/1234567890?foo=bar
规则:
- 数字总是在斜杠之后
- 数字可以有不同的长度
- 正则表达式必须检查 URL 中是否有
/p/
- 数字可能位于 URL 的末尾,或者后面可能有变量
我的尝试:
'/p'/([0-9]+)
这与第一个和第二个匹配,但与第三个不匹配。所以我尝试了:
'/p'/[^'/?]*'/?([0-9]+)
没有快乐。
正则表达式 101
正则表达式可能不是这项工作的正确工具。 看起来在每种情况下,使用 URL 解析器拆分 URL 会更有意义。 从您的示例中可以看出,数字部分似乎始终是 URL 路径部分中的最后一项。 我不确定您使用什么语言,但许多语言都提供了可以将 URL 解析为其组成部分的函数。
$path = parse_url($url, PHP_URL_PATH);
if(strpos($path, "/p/") === 0) {
$base = basename($path);
} else {
// error
}
每次都有效,假设$url是您要解析的字符串。
我扩展了您的版本,它现在适用于所有示例:
'/p'/(.+'/)*('d+)('?.+=.+(&.+=.+)*)?$
如果您不在乎 URL 是否有效,您可以将正则表达式缩小到:
'/p'/(.+'/)*('d+)($|'?)
https://regex101.com/r/pW5qB3/2
如果我理解得很好,你想要的数字只能是:
- 紧跟在 URL 的最后一个斜杠之后
- 不能成为变量的一部分,即
/p/123?foo=bar456
匹配123
和
/p/foobar?foo=bar456
什么都不匹配
然后,您可以使用以下正则表达式:
(?=/p/).*/'K'd+
解释
(?=/p/) # lookahead: check '/p/' is in the URL
.*/ # go to the last '/' thanks to greediness
'K # leave everything we have so far out of the final match
'd+ # select the digits just after the last '/'
为避免转义正斜杠,请勿将它们用作正则表达式分隔符:#(?=/p/).*/'K'd+#
会做得很好。
在此处查看演示。
'/p'/(?:.*'/)?('d+)'b
你可以试试这个。这将根据您的编码捕获整数。请参阅演示。抓取捕获或组。
https://regex101.com/r/dU7oN5/29
$re = "/''/p''/(?:.*''/)?(''d+)''b/";
$str = "http://www.example.com/p/12345678'nhttp://www.example.com/p/12345678?foo=bar'nhttp://www.example.com/p/some-text-123/1234567890?foo=bar";
preg_match_all($re, $str, $matches);
var regex = new Regex(@"/(?<ticket>'d+)");
var subject = "http://www.example.com/p/some-text-123/1234567890?foo=bar";
var ticket = regex.Match(subject).Groups["ticket"].Value;
输出:1234567890