正则表达式捕获组始终是第一个

时间:2015-12-07 11:04:37

标签: php regex

我有这个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

它工作正常,但我有一个问题,捕获组是一些匹配的第二和第三。我喜欢将捕获的字符串始终匹配为第一个捕获组。这可能吗?

2 个答案:

答案 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'];

demo

或者,由于您要查找的内容始终位于模式的末尾,因此您根本不需要使用\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];