在Ruby中检查字符串是否包含数组中的任何子字符串

49

我正在使用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中,最好的方法是什么?

5个回答

124

有多种方法可以做到这一点。您可以使用 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"

1
为了安全起见,您应该转义正则表达式中的单词(以防存在任何正则表达式特殊字符):r = /#{words.map{|w|Regexp.escape(w)}.join('|')}/ - Phrogz
@steenslag 谢谢!我从来没有见过那个方法(自至少1.8.6版以来就有了!)。 - Phrogz
@steenslag 那么不需要进行连接吗?我只需要执行联合操作,它就会进行转义?太棒了... - Hommer Smith
19
我尝试了这两种方法并进行了一百万次的基准测试: .any? # => ( 0.877526) r = Regexp.union(*words); r === string # => ( 17.374344) 仅供参考。 - index
你的正则表达式正是我所需要的。谢谢! - Buildzzz
4
虽然有点晚,但@index的基准仍然有效且仍然正确。只是现在机器处理得更快了,.any? # => ( 0.160000 ); union => ( 6.410000 ) - Shrinath

3
如果image/jpeg; name=example3.jpg是一个字符串:
("image/jpeg; name=example3.jpg".split("; ") & VALID_CONTENT_TYPES).length > 0

即,有效内容类型数组和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 }

2
# will be true if the content type is included    
VALID_CONTENT_TYPES.include? attachment.content_type.gsub!(/^(image\/[a-z]+).+$/, "\1") 

0

我认为我们可以将这个问题分为两个部分:

  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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接