Почему эта проверка регулярных выражений возвращает true для этой строки? - PullRequest
0 голосов
/ 08 февраля 2011

Мне нужно регулярное выражение, которое определит, является ли строка 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 ]

4 голосов
/ 08 февраля 2011

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.

2 голосов
/ 08 февраля 2011

Здесь не нужно регулярных выражений (как обычно).

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

Больше документов на: http://ruby -doc.org / stdlib /

2 голосов
/ 08 февраля 2011

Ваше регулярное выражение может быть сокращено как:

#^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
1 голос
/ 08 февраля 2011

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

(http:|https:)

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

^(http:|https:).*$
0 голосов
/ 08 февраля 2011

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

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

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

0 голосов
/ 08 февраля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...