0

我有一个来自输入表单的字符串,并希望使用不区分大小写的比较将它与许多可能的验证字符串进行比较,true如果找到匹配项则返回。

例如,如果输入是input = 'florida'(or 'FL', or 'flor.') 并且我将它与validate = ['fl', 'florida'], 或一些这样的验证数组进行比较,它应该返回true.

我知道我可以将标签select与明确的选项列表一起使用,但是,这只是一个示例。就我而言,该字段可以返回多种类型的字符串,因此我试图找到一个很好的“解析”解决方案。似乎是 Ruby 擅长的那种问题?

4

2 回答 2

2

比较多个字符串的最快方法是使用正则表达式,尤其是当您可以对它们进行变体时。Ruby 有一些帮助方法可以使这更容易:

validate = ['fl', 'florida']

regex = /\b(?:#{ Regexp.union(validate.sort_by{ |s| [-s.size, s] }).source })\b/i
regex # => /\b(?:florida|fl)\b/i
'FL'[regex] # => "FL"
'florida'[regex] # => "florida"

'flor.'[regex] # => nil

请记住,在 Ruby 中,只有nilfalse是假值,其他所有结果都被认为是真的。强制真/假值的捷径是使用!!( not not)。将上述结果与以下结果进行比较:

!!'FL'[regex] # => true
!!'florida'[regex] # => true
!!'flor.'[regex] # => false

'flor.'不匹配,因为模式正在寻找全字匹配,由于周围的\b(字边界)标记。删除它们,或者添加flor.到模式中可以解决这个问题:

validate = ['fl', 'florida', 'flor']
regex = /\b(?:#{ Regexp.union(validate.sort_by{ |s| [-s.size, s] }).source })\b/i
'flor.'[regex] # => "flor"

'flor.'不能使用,因为which\b与尾随.. flor.删除\b

validate = ['fl', 'florida', 'flor.']
regex = /(?:#{ Regexp.union(validate.sort_by{ |s| [-s.size, s] }).source })/i
'flor.'[regex] # => "flor."

validate将数组中的值传递给时,您可以非常富有表现力,Regexp.union但要注意union转义字符串的内容以保护正则表达式中的特殊字符:

Regexp.union(%w[a \b dollars$ . * ? +]) # => /a|\\b|dollars\$|\.|\*|\?|\+/

你可以控制这个:

patterns = %w[a \b dollars$ . \* \? \+]
/#{ patterns.join('|') }/ # => /a|\b|dollars$|.|\*|\?|\+/

有时我分几个步骤构建一个模式,有时我可以一次完成。这是你必须尝试的东西。

回到开头。联合模式更快的原因是正则表达式引擎非常快,并且字符串只搜索一次,即使模式中的多个元素是 OR'd(使用|)。

于 2013-07-20T03:34:22.377 回答
1

我通常只是将值放入一个数组中,然后使用包含?方法,如果输入匹配数组的任何元素,则返回 true。

['fl', 'florida', 'FL'].include?(input)
于 2013-07-20T01:29:27.173 回答