这有点难以在标题中总结,但这是我的问题:
(?:(?:http|https):\\/\\/)?(?:\\/\\/www\\.)?youtube.com\\/watch\\?(?:.*)v=(\\w{11}).*
鉴于下面给出的表达式,我真的不明白为什么ftp://www.youtube.com/watch?v=F5eScJmYZZ8
匹配。我没有尝试将^
添加到表达式开头,但之后,我的表达式不再匹配任何东西(这在Java中完成,这解释了加倍的反斜杠)。
如何接受ftp,因为它显然未在(http | ftp)中列出?
修改
准确地说,这是允许的:
,别无其他。
答案 0 :(得分:3)
因为?
部分之后的http
意味着它是可选的。使用+
代替?
。
此外,您在//
两次后检查http
。
\s*
允许开头的空格。如果您不想允许空格(即输入文本只包含1个匹配项),请改用^
。
以下是满足您所有附加要求的正则表达式:
\s*(?:(http|https)\:\/\/)?(?:www\.)?youtube.com\/watch\?(?:.*)v=(\w{11}).*
答案 1 :(得分:2)
因为前导(?:(?:http|https):\\/\\/)?
是可选的。这就是组末尾的问号表示(最多匹配一个,即只有匹配时)。
前导^
应阻止与ftp
的匹配。你能发布你试过的失败的正则表达式(使用^
)吗?
<强>更新强>
啊哈!它与^
匹配,因为http
组是可选的,并且在匹配之前可以有任何内容(例如cheeseyoutube.com/...
匹配)。在正则表达式的开头添加^
可以修复此问题,但正则表达式存在另一个问题:www
组正在尝试匹配两个斜杠(如Justin's answer中首先指出的那样),一旦http
组已经与那些斜线匹配,它就不能。因此www
组无法匹配(很好,因为它是可选的),但youtube
部分无法匹配,因为路上有一个无法匹配的www
!
这可以解决您的问题:
^(?:(?:http|https):\\/\\/)?(?:www\\.)?youtube.com\\/watch\\?(?:.*)v=(\\w{11}).*