これが私がそれについて行く方法です:
regex = /\b(?:#{ Regexp.union(str.split('').permutation.map{ |a| a.join }).source })\b/
# => /(?:act|atc|cat|cta|tac|tca)/
%w[
cat act tca atc tac cta
ca ac cata
].each do |w|
puts '"%s" %s' % [w, w[regex] ? 'matches' : "doesn't match"]
end
その出力:
"cat" matches
"act" matches
"tca" matches
"atc" matches
"tac" matches
"cta" matches
"ca" doesn't match
"ac" doesn't match
"cata" doesn't match
Regexp.union
私は多くのことに配列を渡す手法を使用しています。gsub
私は特にハッシュのキーをうまく処理し、テキストテンプレートをすばやく検索/置換するためにハッシュを渡します。これは、gsub
ドキュメントの例です。
'hello'.gsub(/[eo]/, 'e' => 3, 'o' => '*') #=> "h3ll*"
Regexp.unionは正規表現を作成します。生成される実際のパターンを抽出するときは、source
代わりに使用することが重要です。to_s
puts regex.to_s
=> (?-mix:\b(?:act|atc|cat|cta|tac|tca)\b)
puts regex.source
=> \b(?:act|atc|cat|cta|tac|tca)\b
to_s
文字列内にパターンのフラグがどのように埋め込まれているかに注目してください。それらを予期しない場合は、誤ってそのパターンを別のパターンに埋め込んでしまう可能性があります。これは、期待どおりに動作しません。そこに行って、それをして、証拠としてへこんだヘルメットを持ってください。
本当に楽しみたい場合は、CPANで利用可能なPerl Regexp::Assembleモジュールを調べてください。これに加えて、List :: Permutorを使用すると、より複雑なパターンを生成できます。このような単純な文字列では、スペースをあまり節約できませんが、長い文字列や目的のヒットの大きな配列では、大きな違いが生じる可能性があります。残念ながら、Rubyにはこのようなものはありませんが、単語または単語の配列を使用して単純なPerlスクリプトを記述し、正規表現を生成して返すことができます。
use List::Permutor;
use Regexp::Assemble;
my $regex_assembler = Regexp::Assemble->new;
my $perm = new List::Permutor split('', 'act');
while (my @set = $perm->next) {
$regex_assembler->add(join('', @set));
}
print $regex_assembler->re, "\n";
(?-xism:(?:a(?:ct|tc)|c(?:at|ta)|t(?:ac|ca)))
RubyでRegexp::Assembleを使用する方法の詳細については、「Rubyで何百ものテキスト置換を実行する効率的な方法はありますか? 」を参照してください。