Die einfache Ausgangspunkt ist:
words = %w[one two three]
/#{ Regexp.union(words).source }/i # => /one|two|three/i
Sie wahrscheinlich sicherstellen möchten, sind Sie nur Worte so zwicken es passend:
/\b#{ Regexp.union(words).source }\b/i # => /\bone|two|three\b/i
Für Sauberkeit und Klarheit Ich bevorzuge die Verwendung einer nicht einfangenden Gruppe:
/\b(?:#{ Regexp.union(words).source })\b/i # => /\b(?:one|two|three)\b/i
Verwenden Sie ist wichtig.Wenn Sie ein Regexp-Objekt erstellen, hat es eine Vorstellung von den Fahnen (i
, m
, x
), die auf das Objekt anwenden und diejenigen, erhalten in den String interpoliert:
"#{ /foo/i }" # => "(?i-mx:foo)"
"#{ /foo/ix }" # => "(?ix-m:foo)"
"#{ /foo/ixm }" # => "(?mix:foo)"
oder
(/foo/i).to_s # => "(?i-mx:foo)"
(/foo/ix).to_s # => "(?ix-m:foo)"
(/foo/ixm).to_s # => "(?mix:foo)"
Das ist Fein, wenn das erzeugte Muster alleine steht, aber wenn es in eine Zeichenkette interpoliert wird, um andere Teile des Musters zu definieren, beeinflussen die Flags jeden Unterausdruck:
/\b(?:#{ Regexp.union(words) })\b/i # => /\b(?:(?-mix:one|two|three))\b/i
Dig in die Regexp-Dokumentation und Sie werden sehen, dass ?-mix
"ignore-case" innerhalb (?-mix:one|two|three)
deaktiviert, obwohl das Gesamtmuster mit i
gekennzeichnet ist, was zu einem Muster führt, das nicht das tut, was Sie wollen und wirklich ist schwer zu debuggen: Statt
'foo ONE bar'[/\b(?:#{ Regexp.union(words) })\b/i] # => nil
, entfernt source
die Flagge inneren Ausdruck, das Muster zu machen tun, was man erwarten würde:
/\b(?:#{ Regexp.union(words).source })\b/i # => /\b(?:one|two|three)\b/i
und
'foo ONE bar'[/\b(?:#{ Regexp.union(words).source })\b/i] # => "ONE"
Sie können bauen Sie Ihre Muster Regexp.new
und vorbei in den Flaggen mit:
regexp = Regexp.new('(?:one|two|three)', Regexp::EXTENDED | Regexp::IGNORECASE) # => /(?:one|two|three)/ix
aber als der Ausdruck wird immer komplexer wird es unhandlich. Das Erstellen eines Musters mit der String-Interpolation bleibt einfacher zu verstehen.
Beachten Sie, dass Ihre erste Option 'Regexp.new (Regexp.union (strings) .to_s, true)' '/ (? - mix: eins | zwei | drei)/i' zurückgibt, was wahrscheinlich nicht das ist, was Sie wollen, weil die Wörter immer noch Groß- und Kleinschreibung übereinstimmen ('-i'). – Stefan