为什么此正则表达式检查对此字符串返回true?

时间:2011-02-08 09:44:28

标签: ruby-on-rails ruby regex

我需要一个正则表达式来确定字符串是否是推文URL。我有这个

Regexp.new(/http:|https:\/\/(twitter\.com\/.*\/status\/.*|twitter\.com\/.*\/statuses\/.*|www\.twitter\.com\/.*\/status\/.*|www\.twitter\.com\/.*\/statuses\/.*|mobile\.twitter\.com\/.*\/status\/.*|mobile\.twitter\.com\/.*\/statuses\/.*)/i)

为什么它会在以下情况下返回?

"http://i.stack.imgur.com/QdOS0.jpg".match(Regexp.new(/http:|https:\/\/(twitter\.com\/.*\/status\/.*|twitter\.com\/.*\/statuses\/.*|www\.twitter\.com\/.*\/status\/.*|www\.twitter\.com\/.*\/statuses\/.*|mobile\.twitter\.com\/.*\/status\/.*|mobile\.twitter\.com\/.*\/statuses\/.*)/i))? true : false
    => true

6 个答案:

答案 0 :(得分:4)

http:将始终匹配以http:

开头的网址

尝试以下方法:

/https?:\/\/(twitter\.com\/.*\/status\/.*|twitter\.com\/.*\/statuses\/.*|www\.twitter\.com\/.*\/status\/.*|www\.twitter\.com\/.*\/statuses\/.*|mobile\.twitter\.com\/.*\/status\/.*|mobile\.twitter\.com\/.*\/statuses\/.*)/i

问号会使s成为可选项,从而匹配httphttps

答案 1 :(得分:2)

你的正则表达式可以缩写为:

#^https?://(:?www\.|mobile\.)?twitter\.com/.*?/status(:?es)?/.*#i

<强>解释

#                       regex delimiter
^                       start of line
https?                  http or https
://                     ://
(:?                     start of non capture group
www\.|mobile\.          www. or mobile.
)?                      end of group
twitter\.com/           twitter.com
.*?                     any number of any char not greedy
/status                 /status
(:?es)?                 non capture group that contains possibly  `es`
/.*                     / followed by any number of any char
$                       end of string
#i                      delimiter and case insensitive

答案 2 :(得分:2)

这里不需要正则表达式(像往常一样)。

require 'uri'
uri = URI.parse("http://www.twitter.com/status/12345")
p uri.host.split('.')[-2] == 'twitter' # returns true

更多文档位于:http://ruby-doc.org/stdlib/

答案 3 :(得分:1)

您应该将您的OR条款分组,如下所示:

(http:|https:)

此外,指定它的开头和结尾也没有坏处:

^(http:|https:).*$

答案 4 :(得分:0)

你的正则表达式的开头指定了一个只是'http:'的选项,它自然地匹配你正在测试的URL。根据您需要检查的严格程度,您可以从正则表达式的开头删除http / https部分。

答案 5 :(得分:0)

虽然许多其他答案显示了更好的正则表达式,但答案是因为/foo|bar/将与foobar匹配,而您所写的内容为/http:|.../,因此所有网址将匹配。

请参阅@ giraff的答案,了解如何编写替代方案以达到预期效果,或@ M42或@Koraktor的答案以获得更好的正则表达式。

正如评论中所述,请注意您可以将正则表达式文字写为%r{...}而不是/.../,这在您想要使用/字符时很好你的正则表达式没有逃脱它们。