我有这个PHP正则表达式:
https?://(?:[a-z0-9]+\.)?livestream\.com/(?:(accounts/[0-9]+/events/[0-9]+(?:/videos/[0-9]+)?)|[^\s/]+/video\?clipId=([^\s&]+)|([^\s/]+))
我希望将以下网址与结果相匹配。
http://original.livestream.com/bethanychurchnh = bethanychurchnh
http://original.livestream.com/bethanychurchnh/video?clipId=flv_b54a694b-043c-4886-9f35-03c8008c23 = flv_b54a694b-043c-4886-9f35-03c8008c23
http://livestream.com/accounts/142499/events/3959775 = accounts/142499/events/3959775
http://livestream.com/accounts/142499/events/3959775/videos/83958146 = /accounts/142499/events/3959775/videos/83958146
它工作正常,但我有一个问题,捕获组是一些匹配的第二和第三。我喜欢将捕获的字符串始终匹配为第一个捕获组。这可能吗?
答案 0 :(得分:2)
您可以在正则表达式中使用分支重置:
https?:\/\/(?:[a-z0-9]+\.)?livestream\.com\/(?|(accounts\/[0-9]+\/events\/[0-9]+(?:\/videos\/[0-9]+)?)|[^\s\/]+\/video\?clipId=([^\s&]+)|([^\s\/]+))
^^
请参阅regex demo
请参阅branch reset at regular-expressions.info的说明:
分支重置组内的Alternatives共享相同的捕获组。语法为
(?|regex)
,其中(?|
打开组,正则表达式是任何正则表达式。如果您不在分支重置组内使用任何交替或捕获组,则其特殊功能不起作用。然后它充当non-capturing group。
答案 1 :(得分:1)
其他可能性,您可以允许使用(?J)
$pattern = '~(?J)https?://(?:[a-z0-9]+\.)?livestream\.com/
(?:
(?<id>accounts/[0-9]+/events/[0-9]+(?:/videos/[0-9]+)?)
|
[^\s/]+/video\?clipId=(?<id>[^\s&]+)
|
(?<id>[^\s/]+)
)~x';
if (preg_match($pattern, $text, $m))
echo $m['id'];
或者,由于您要查找的内容始终位于模式的末尾,因此您根本不需要使用\K
功能删除整个匹配结果左侧的所有内容的捕获组:< / p>
$pattern = '~https?://(?:[a-z0-9]+\.)?livestream\.com/ \K
(?:
accounts/[0-9]+/events/[0-9]+(?:/videos/[0-9]+)?
|
[^\s/]+(?:/video\?clipId=\K[^\s&]+)?
)~x';
if (preg_match($pattern, $text, $m))
echo $m[0];