Как объединить условия регулярного выражения Ruby - PullRequest
0 голосов
/ 26 апреля 2018

Мне нужно проверить, является ли строка действительным URL-адресом изображения.Я хочу проверить начало и конец строки следующим образом:

  • Должен начинаться с http (s):
  • Должен заканчиваться на .jpg | .png | .gif |.jpeg

Пока у меня есть:

(https?:)

Кажется, я не могу указать начало строки \A, объединить шаблоны и проверить конец строки.

Тестовые строки:

"http://image.com/a.jpg"
"https://image.com/a.jpg"
"ssh://image.com/a.jpg"
"http://image.com/a.jpeg"
"https://image.com/a.png"
"ssh://image.com/a.jpeg"

Пожалуйста, смотрите http://rubular.com/r/PqERRim5RQ

Использование Ruby 2.5

Ответы [ 3 ]

0 голосов
/ 26 апреля 2018

Вы можете использовать

reg = %r{\Ahttps?://.*\.(?:png|gif|jpe?g)\z}

Суть:

  1. Когда тестирует в онлайн-тестировщиках регулярных выражений, вы тестируете одну многострочную строка, но в реальной жизни вы будете проверять строки как отдельные строки.Итак, в этих тестерах используйте ^ и $, а в реальном коде используйте \A и \z.
  2. Чтобы сопоставить строку, а не строку, вам нужно \A и \z anchors
  3. Используйте синтаксис %r{pat}, если в вашем шаблоне много /, он чище.

Онлайн-тест Ruby :

urls = ['http://image.com/a.jpg',
        'https://image.com/a.jpg',
        'ssh://image.com/a.jpg',
        'http://image.com/a.jpeg',
        'https://image.com/a.png',
        'ssh://image.com/a.jpeg']
reg = %r{\Ahttps?://.*\.(?:png|gif|jpe?g)\z}
urls.each { |url|
    puts "#{url}: #{(reg =~ url) == 0}"
}

Выход:

http://image.com/a.jpg: true
https://image.com/a.jpg: true
ssh://image.com/a.jpg: false
http://image.com/a.jpeg: true
https://image.com/a.png: true
ssh://image.com/a.jpeg: false
0 голосов
/ 26 апреля 2018

Ответы здесь довольно хорошие, но если вы хотите избежать использования сложного регулярного выражения и более четко донести свои намерения до читателя, вы можете позволить URI и File сделать тяжелую работу за вас.

(А поскольку вы используете 2.5, давайте использовать #match? вместо других методов сопоставления регулярным выражениям.)

def valid_url?(url)
  # Let URI parse the URL.
  uri = URI.parse(url)
  # Is the scheme http or https, and does the extension match expected formats?
  uri.scheme.match?(/https?/i) && File.extname(uri.path).match?(/(png|jpe?g|gif)/i)
rescue URI::InvalidURIError
  # If it's an invalid URL, URI will throw this error.
  # We'll return `false`, because a URL that can't be parsed by URI isn't valid.
  false
end

urls.map { |url| [url, valid_url?(url)] }

#=> Results in:
'http://image.com/a.jpg', true
'https://image.com/a.jpg', true
'ssh://image.com/a.jpg', false
'http://image.com/a.jpeg', true
'https://image.com/a.png', true
'ssh://image.com/a.jpeg', false
'https://image.com/a.tif', false
'http://t.co.uk/proposal.docx', false
'not a url', false
0 голосов
/ 26 апреля 2018

Используя свою собственную демонстрацию, вы можете использовать

^https?:\/\/.*(?:\.jpg|\.png|\.gif|\.jpeg)$

См. модифицированную демонстрацию .


Можно даже упростить ее до:
^https?:\/\/.*\.(?:jpe?g|png|gif)$

См. демо для последнего .


В основном используются якоря (^ и $) с обеих сторон, указывающие начало / конец строки.Кроме того, помните, что вам нужно экранировать точку (\.), если вы хотите получить ..
В разделе комментариев происходит некоторая двусмысленность, поэтому позвольте мне уточнить это:
^  - is meant for the start of a string 
     (or a line in multiline mode, but in Ruby strings are always in multiline mode)
$  - is meant for the end of a string / line
\A - is the very start of a string (irrespective of multilines) 
\z - is the very end of a string (irrespective of multilines) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...