我想编写一个实用程序函数/模块,它将为字符串提供简单的通配符/ glob匹配。我没有使用正则表达式的原因是用户将最终使用某种配置文件提供匹配的模式。我找不到任何这样稳定的宝石 - 试过小丑,但是设置有问题。
我正在寻找的功能很简单。例如,给定以下模式,以下是匹配项:
pattern | test-string | match
========|=====================|====================
*hn | john, johnny, hanna | true , false, false # wildcard , similar to /hn$/i
*hn* | john, johnny, hanna | true , true , false # like /hn/i
hn | john, johnny, hanna | false, false, false # /^hn$/i
*h*n* | john, johnny, hanna | true , true , true
etc...
我希望这样做尽可能高效。我考虑过从模式字符串创建正则表达式,但这在运行时似乎效率很低。有关此实施的任何建议吗?感谢。
编辑:我正在使用ruby 1.8.7
答案 0 :(得分:13)
我不明白为什么你认为它效率低下。关于这些事情的预测是众所周知的不可靠的,你应该在你向前弯腰寻找更快的方式之前决定它太慢。然后你应该对它进行分析,以确保问题所在(顺便说一下,从切换到1.9时,平均速度提升3-4倍)
无论如何,这样做应该很容易,例如:
class Globber
def self.parse_to_regex(str)
escaped = Regexp.escape(str).gsub('\*','.*?')
Regexp.new "^#{escaped}$", Regexp::IGNORECASE
end
def initialize(str)
@regex = self.class.parse_to_regex str
end
def =~(str)
!!(str =~ @regex)
end
end
glob_strs = {
'*hn' => [['john', true, ], ['johnny', false,], ['hanna', false]],
'*hn*' => [['john', true, ], ['johnny', true, ], ['hanna', false]],
'hn' => [['john', false,], ['johnny', false,], ['hanna', false]],
'*h*n*' => [['john', true, ], ['johnny', true, ], ['hanna', true ]],
}
puts glob_strs.all? { |to_glob, examples|
examples.all? do |to_match, expectation|
result = Globber.new(to_glob) =~ to_match
result == expectation
end
}
# >> true
答案 1 :(得分:1)
def create_regex(pattern)
if pattern[0,1] != '*'
pattern = '[^\w\^]' + pattern
end
if pattern[-1,1] != '*'
pattern = pattern + '[^\w$]'
end
return Regexp.new( pattern.gsub(/\*/, '.*?') )
end
此方法应返回正则表达式
PS:未经测试:D