2011-02-08 2 views
0

Мне нужно регулярное выражение, которое определит, является ли строка URL-адресом твита. У меня есть этоПочему эта проверка регулярного выражения возвращает true для этой строки?

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 
+0

Если вы используете Regexp.new ('HTTP: //', 'я'), вы в безопасности себя некоторые миновать беды. – giraff

+1

см. [Strfriend] (http: //strfriend.com/vis? Re = http% 3A | https% 3A \% 2F \% 2F% 28twitter \ .com \% 2F. * \% 2Fstatus \% 2F. * | твиттер \ .com \% 2F * \% 2Fstatuses \% 2F * |.. WWW \ .twitter \ .com \% 2F * \% 2Fstatus \% 2F * |.. WWW \ .twitter \ .com \% 2F. * \% 2Fstatuses \% 2F * |.. мобильный \ .twitter \ .com \% 2F * \% 2Fstatus \% 2F * |.. мобильный \ .twitter \ .com \% 2F * \% 2Fstatuses \% 2F. *% 29) – giraff

+0

Ответ уже дан, но я просто хочу оставить этот сайт здесь, он всегда очень помогает мне в борьбе с регулярными выражениями: [Rubular] (http: // bit.ly/e8G1IM) – Maran

ответ

0

В начало вашего регулярного выражения указан вариант только «http:», который, естественно, совпадает с URL-адресом, который вы тестируете. В зависимости от того, насколько строго вам нужен ваш чек, вы можете просто удалить части http/https с начала регулярного выражения.

4

http: всегда будет соответствовать URL, начиная с 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 необязательными, таким образом, соответствие http или https.

1

Вы должны сгруппировать OR-Морозы, как это:

(http:|https:) 

Кроме того, не мешало бы указать начало и конец его:

^(http:|https:).*$ 
+1

Или, если вам не нужно фиксировать предложение, '(?: Http: | https:)'. – Phrogz

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 
0

Хотя многие другие ответы показывают вам лучше регулярное выражение, то ответ, потому что /foo|bar/ будет соответствовать либо foo или bar, и то, что вы написали было /http:|.../, поэтому все URL-адреса будут совпадать.

См. Ответ @ giraff за то, как вы могли написать чередование, чтобы делать то, что вы ожидаете, или ответы @ M42 или @ Koraktor для лучшего регулярного выражения.

И, как писал в комментариях, обратите внимание, что вы можете написать регулярное выражение буквального, как %r{...} вместо /.../, что приятно, когда вы хотите использовать / символы в регулярных выражениях, не избежать их.

+0

Мне нравится% r-Syntax, но как бы вы добавили к нему i-модификатор? – giraff

+0

@giraff '% r {...} i' – Phrogz

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/

+0

+1 для разрезания на погоню и обхода пули регулярных выражений. –