如何结合Ruby regexp条件

时间:2018-04-26 05:53:24

标签: ruby-on-rails ruby regex

我需要检查一个字符串是否是有效的图片网址。 我想检查字符串的开头和字符串的结尾,如下所示:

  • 必须以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 :(得分:5)

使用您自己的演示,您可以使用

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

请参阅the modified demo

<小时/> 人们甚至可以将其简化为:

^https?:\/\/.*\.(?:jpe?g|png|gif)$

a demo for the latter as well

<小时/> 这基本上在两侧使用锚点(^$),指示字符串的开始/结束。此外,请记住,如果您想要\.,则需要转义点(.)。 评论部分中有一些含糊不清的内容,所以让我澄清一下:

^  - 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) 

答案 1 :(得分:3)

您可以使用

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

重点是:

  1. 当在线正则表达式测试人员测试时,您正在测试单个多行字符串,但在现实生活中,您将验证行单独字符串。因此,在这些测试人员中,使用^$并使用实际代码,使用\A\z
  2. 要匹配字符串而不是行,您需要\A\z锚点
  3. 如果您的模式中有许多%r{pat},则使用/语法,它更清晰。
  4. 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}"
    }
    

    输出:

    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
    

答案 2 :(得分:1)

这里的答案非常好,但是如果您想避免使用复杂的正则表达式并更清楚地向读者传达您的意图,您可以让URIFile为您做繁重的工作

(由于您使用的是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