Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine Ruby regexp conditions

I need to check if a string is valid image url. I want to check beginning of string and end of string as follows:

  • Must start with http(s):
  • Must end by .jpg|.png|.gif|.jpeg

So far I have:

(https?:)

I can't seem to indicate beginning of string \A, combine patterns, and test end of string.

Test strings:

"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"

Please see http://rubular.com/r/PqERRim5RQ

Using Ruby 2.5

like image 678
olimart Avatar asked Jan 03 '23 11:01

olimart


2 Answers

Using your very own demo, you could use

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

See the modified demo.


One could even simplify it to:
^https?:\/\/.*\.(?:jpe?g|png|gif)$

See a demo for the latter as well.


This basically uses anchors (^ and $) on both sides, indicating the start/end of the string. Additionally, please remember that you need to escape the dot (\.) if you want to have ..
There's quite some ambiguity going on in the comments section, so let me clarify this:
^  - 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) 
like image 64
Jan Avatar answered Jan 05 '23 14:01

Jan


You may use

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

The point is:

  1. When testing at online regex testers, you are testing a single multiline string, but in real life, you will validate lines as separate strings. So, in those testers, use ^ and $ and in real code, use \A and \z.
  2. To match a string rather than a line you need \A and \z anchors
  3. Use %r{pat} syntax if you have many / in your pattern, it is cleaner.

Online Ruby test:

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}"
}

Output:

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
like image 34
Wiktor Stribiżew Avatar answered Jan 05 '23 14:01

Wiktor Stribiżew