正则表达式 - 不在列表中,但仍然匹配

时间:2011-06-26 21:02:51

标签: regex

这有点难以在标题中总结,但这是我的问题:

(?:(?:http|https):\\/\\/)?(?:\\/\\/www\\.)?youtube.com\\/watch\\?(?:.*)v=(\\w{11}).*

鉴于下面给出的表达式,我真的不明白为什么ftp://www.youtube.com/watch?v=F5eScJmYZZ8匹配。我没有尝试将^添加到表达式开头,但之后,我的表达式不再匹配任何东西(这在Java中完成,这解释了加倍的反斜杠)。

如何接受ftp,因为它显然未在(http | ftp)中列出?

修改

准确地说,这是允许的:

  • http(s):// www。[...]
  • HTTP(S):// [...]
  • 万维网。[...]
  • [...]

,别无其他。

2 个答案:

答案 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}).*