【问题标题】:Check if string contains any substring in an array in Ruby检查字符串是否包含Ruby数组中的任何子字符串
【发布时间】:2012-04-30 05:31:57
【问题描述】:

我正在使用 Tmail 库,对于电子邮件中的每个附件,当我使用attachment.content_type 时,有时我不仅会得到内容类型,还会得到名称。例子:

image/jpeg; name=example3.jpg

image/jpeg; name=example.jpg

image/jpeg; name=photo.JPG

image/png

我有一组像这样的有效内容类型:

VALID_CONTENT_TYPES = ['image/jpeg']

我希望能够检查内容类型是否包含在任何有效的内容类型数组元素中。

在 Ruby 中这样做的最佳方式是什么?

【问题讨论】:

    标签: ruby regex substring


    【解决方案1】:

    有多种方法可以做到这一点。您可以使用Enumerable#any? 检查每个字符串,直到找到匹配项:

    str = "alo eh tu"
    ['alo','hola','test'].any? { |word| str.include?(word) }
    

    虽然将字符串数组转换为正则表达式可能会更快:

    words = ['alo','hola','test']
    r = /#{words.join("|")}/ # assuming there are no special chars
    r === "alo eh tu"
    

    【讨论】:

    • 为了安全起见,您应该转义正则表达式中的单词(以防出现任何正则表达式特殊字符):r = /#{words.map{|w|Regexp.escape(w)}.join('|')}/
    • @steenslag 谢谢!我从未见过这种方法(至少从 1.8.6 开始就存在!)。
    • @steenslag 所以不需要加入吗?我可以做联合,它会逃跑吗?太棒了...
    • 我都试过了,并尝试对其进行基准测试 1_000_000x:.any? # => ( 0.877526) r = Regexp.union(*words); r === string # => ( 17.374344) 仅供参考。
    • 晚了几年,但 @index 的基准仍然有效并且仍然正确。只有那些机器现在处理它的速度更快,.any? # => ( 0.160000 ); union => ( 6.410000 )
    【解决方案2】:

    如果image/jpeg; name=example3.jpg 是字符串:

    ("image/jpeg; name=example3.jpg".split("; ") & VALID_CONTENT_TYPES).length > 0
    

    即VALID_CONTENT_TYPES 数组和attachment.content_type 数组(包括类型)的交集(两个数组共有的元素)应该大于0。

    这至少是许多种方式中的一种。

    【讨论】:

      【解决方案3】:

      所以如果我们只想要匹配的存在:

      VALID_CONTENT_TYPES.inject(false) do |sofar, type| 
          sofar or attachment.content_type.start_with? type
      end
      

      如果我们想要匹配,这将给出数组中匹配字符串的列表:

      VALID_CONTENT_TYPES.select { |type| attachment.content_type.start_with? type }
      

      【讨论】:

        【解决方案4】:
        # will be true if the content type is included    
        VALID_CONTENT_TYPES.include? attachment.content_type.gsub!(/^(image\/[a-z]+).+$/, "\1") 
        

        【讨论】:

          【解决方案5】:

          我认为我们可以将这个问题一分为二:

          1. 如何清理不需要的数据
          2. 如何检查清理后的数据是否有效

          第一个在上面得到了很好的回答。对于第二个,我会做以下事情:

          (cleaned_content_types - VALID_CONTENT_TYPES) == 0
          

          这个解决方案的好处是您可以轻松创建一个变量来存储不需要的类型,以便稍后列出它们,如下例所示:

          VALID_CONTENT_TYPES = ['image/jpeg']
          cleaned_content_types = ['image/png', 'image/jpeg', 'image/gif', 'image/jpeg']
          
          undesired_types = cleaned_content_types - VALID_CONTENT_TYPES
          if undesired_types.size > 0
            error_message = "The types #{undesired_types.join(', ')} are not allowed"
          else
            # The happy path here
          end
          

          【讨论】:

            猜你喜欢
            • 2015-09-08
            • 2021-12-14
            • 2012-01-05
            • 1970-01-01
            • 2020-12-01
            • 2011-11-09
            • 2013-05-18
            • 2020-11-28
            相关资源
            最近更新 更多