用于匹配子字符串的可选非捕获组

Optional non-capturing group for matching substring

给定以下示例字符串

//www.youtube.com/embed/OYb_N_XEYas?rel=0&showinfo=0
//www.youtube.com/embed/STH9ZpeFH2o

我需要捕获 'embed/' 之后的子字符串,直到字符串末尾或 '?'或 '/' 字符。

如何指定可选的第二个非捕获组?

使用 (embed\/)(.*) 适用于第二个字符串,(embed\/)(.*)(\?|\/) 适用于第一个字符串,但在这两种情况下均无效。

这对两者都有效

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

同时

.*

匹配任意字符

[^\/?]*

匹配除 / 和 ?

之外的所有内容

您可以使用 negated character class 作为

/embed\/[^?\/]*/
  • [^?\/] 匹配 ?/

  • 以外的任何内容
  • * 量词。匹配零次或多次出现的前面的正则表达式

Regex Demo

测试

preg_match("/embed\/[^?\/]*/", "//www.youtube.com/embed/OYb_N_XEYas?rel=0&showinfo=0", $matches);
=> Array ( [0] => embed/OYb_N_XEYas )

preg_match("/embed\/[^?\/]*/", "//www.youtube.com/embed/STH9ZpeFH2o", $matches);
=> Array ( [0] => embed/STH9ZpeFH2o )

你也可以尝试在非贪婪之后向前看 .*?

/embed\/.*?(?=(?:\?|\/|$))/
  • (?=(?:\?|\/|$))积极展望未来。检查匹配的字符串是否后跟 ?/$,字符串结尾。这是一个断言,不会消耗其中的那些字符。从测试中可以看出,输出不包括 ?

Regex Demo

测试

preg_match("/embed\/.*?(?=(?:\?|\/|$))/", "//www.youtube.com/embed/OYb_N_XEYas?rel=0&showinfo=0", $matches);
=> Array ( [0] => embed/OYb_N_XEYas )

你可以使用这个正则表达式:

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

简而言之,它将匹配所有不是 ?/ 的字符,并将它们放在第 1 组中。因此,无论是否存在此类字符,它都会起作用,即它适用于两个示例字符串。

请注意,这将捕获一个空字符串,如果您不想这样做,只需将 + 替换为 *

我还删除了 embed\/ 周围的组,因为我认为没有理由拥有它。