如何针对模式检查用户输入?

时间:2017-06-09 12:20:33

标签: ruby-on-rails ruby

在我的Ruby on Rails应用程序中,我需要针对由字母,数字和一些特殊字符(如破折号和下划线)组成的模式检查用户输入,我不知道该怎么做。

例如,如果模式为LL-NNNN且用户提交字符串AB-0001,则该模式有效。

如果模式为NN-LL且用户提交77-ABC,则无效。

我正在考虑将每个模式转换为正则表达式,但由于每个用户都可以定义自己的模式(这意味着会有很多模式),我担心这会导致意外的结果。

有谁能告诉我解决这个问题的最佳方法是什么?

5 个答案:

答案 0 :(得分:4)

In a loop, check if each character from the input string satisfies the corresponding pattern-character.

def match?(pattern, input)
  return false if pattern.length != input.length
  pattern.each_char.with_index.all? do |char, i|
    case char
    when 'L' then input[i] =~ /[A-Z]/
    when 'N' then input[i] =~ /[0-9]/
    when '-' then input[i] == '-'
    else raise 'invalid pattern'
    end
  end
end

match?('LL-NNNN', 'AB-1234') #=> true
match?('NN-LL', '77-ABC')    #=> false
match?('NN-LL', '77-99')     #=> false
match?('NN-LL', '77-AB')     #=> true

答案 1 :(得分:4)

如果模式始终是L => LetterN => number-的组合,您可以将其转换为带有Regex.new(value)的正则表达式

对于这两种情况,整个事情看起来都是这样的

def match(pattern, value)
  /\A#{pattern.gsub(/[LN]/, 'L' => '[a-zA-Z]', 'N' => '\d')}\z/.match(value)
end

这仅适用于大写

def match(pattern, value)
  /\A#{pattern.gsub(/[LN]/, 'L' => '[A-Z]', 'N' => '\d')}\z/.match(value)
end

您甚至可以尽早转换为正则表达式格式,并将正则表达式存储在数据库而不是模式中以优化处理时间。

def regex_from_pattern(pattern)
  "\\A#{pattern.gsub(/[LN]/, 'L' => '[a-zA-Z]', 'N' => '\d')}\\z"
end

def match(regex_string, value)
  Regexp.new(regex_string).match(value)
end

答案 2 :(得分:3)

因为我们非常喜欢Ruby中的单行,所以这里很快就会出现这种情况。

将输入字符替换为相应的模式字符:

'AB-1234'.gsub(/[A-Z]/, 'N') #=> "NN-1234"
         .gsub(/[0-9]/, 'L') #=> "NN-LLLL"

将结果与模式进行比较:

'AB-1234'.gsub(/[A-Z]/, 'N').gsub(/[0-9]/, 'L') == 'NN-LLLL'
#=> true

答案 3 :(得分:0)

您可以创建正则表达式构建器,first_name.map do |fname| second_name.map do |sname| "#{fname} #{sname}" end end.flatten #=> ["Tom Ross", "Tom Smith", "Tom Jones", "Tom Wells", "Tom Bain", "Tom Gillespie", "Tom Sutton", "Tom Pearce", "Tom Johnstone", "Tom Lightbody", "John Ross", "John Smith", "John Jones", "John Wells", "John Bain", "John Gillespie", "John Sutton", "John Pearce", "John Johnstone", "John Lightbody", "Allan Ross", "Allan Smith", "Allan Jones", "Allan Wells", "Allan Bain", "Allan Gillespie", "Allan Sutton", "Allan Pearce", "Allan Johnstone", "Allan Lightbody", "Steven Ross", "Steven Smith", "Steven Jones", "Steven Wells", "Steven Bain", "Steven Gillespie", "Steven Sutton", "Steven Pearce", "Steven Johnstone", "Steven Lightbody", "Robert Ross", "Robert Smith", "Robert Jones", "Robert Wells", "Robert Bain", "Robert Gillespie", "Robert Sutton", "Robert Pearce", "Robert Johnstone", "Robert Lightbody", "Lucy Ross", "Lucy Smith", "Lucy Jones", "Lucy Wells", "Lucy Bain", "Lucy Gillespie", "Lucy Sutton", "Lucy Pearce", "Lucy Johnstone", "Lucy Lightbody", "Ruth Ross", "Ruth Smith", "Ruth Jones", "Ruth Wells", "Ruth Bain", "Ruth Gillespie", "Ruth Sutton", "Ruth Pearce", "Ruth Johnstone", "Ruth Lightbody", "Anna Ross", "Anna Smith", "Anna Jones", "Anna Wells", "Anna Bain", "Anna Gillespie", "Anna Sutton", "Anna Pearce", "Anna Johnstone", "Anna Lightbody", "Edith Ross", "Edith Smith", "Edith Jones", "Edith Wells", "Edith Bain", "Edith Gillespie", "Edith Sutton", "Edith Pearce", "Edith Johnstone", "Edith Lightbody", "Jessica Ross", "Jessica Smith", "Jessica Jones", "Jessica Wells", "Jessica Bain", "Jessica Gillespie", "Jessica Sutton", "Jessica Pearce", "Jessica Johnstone", "Jessica Lightbody"] 将对您有所帮助。 我们假设您已经设置了用户定义的模式字母:

Regexp.escape

然后你可以检查用户的模式是否正确:

ALPHABET = 'LN-_:=.\\'

下一步是从他的模式中创建用户定义的输入regexp字符串:

PATTERN_REGEXP = Regexp.new('\A[%s]+\z' % Regexp.escape(ALPHABET))
def is_pattern_ok?(pattern)
  PATTERN_REGEXP =~ pattern
end

并将其保存在DB中的用户设置中。 因此,您可以使用用户定义的模式验证用户输入:

def regexp_str_from(pattern)
  ('\A%s\z' % Regexp.escape(pattern))
    .gsub('N', '\d')
    .gsub('L', '[a-zA-Z]'))
end

已编辑:注意:Regexp.new(regexp_str) =~ user_input 必须避免"意外结果"。

答案 4 :(得分:-1)

您可以在我们的模型中使用它

validates_format_of :your_field_name, with: /(your regex)/i, on: :create