Regexes bestrebt sind, zu entsprechen. Sobald sie eine Übereinstimmung gefunden haben, versuchen sie nicht, eine andere möglicherweise längere zu finden (mit einer wichtigen Ausnahme).
/\b(?i:one|one\ two|three)\b/
wird nie one two
übereinstimmen, weil es immer zuerst one
übereinstimmen wird. Sie würden /\b(?i:one two|one|three)\b/
benötigen, also versucht es zuerst one two
. Die einfachste Möglichkeit, dies zu automatisieren, ist die Sortierung nach den längsten Keywords.
keywords = ['one', 'one two', 'three']
re = Regexp.union(keywords.sort { |a,b| b.length <=> a.length }).source
re = /\b#{re}\b/i;
text = 'Some word one and one two other word'
puts text.scan(re)
Bitte beachte, dass ich die ganze Regex gesetzt Groß- und Kleinschreibung zu sein, einfacher zu lesen als (?:...)
, und dass die Zeichenfolge downcasing redundant ist.
Die Ausnahme ist repetition wie +
, *
und Freunde. Sie sind gierig standardmäßig. .+
wird so viele Zeichen wie möglich übereinstimmen. Das ist gierig. Sie können es faul machen, um das erste, was es sieht, mit einem ?
übereinstimmen. .+?
wird ein einzelnes Zeichen entsprechen.
"A foot of fools".match(/(.*foo)/); # matches "A foot of foo"
"A foot of fools".match(/(.*?foo)/); # matches "A foo"
Ändern Sie die Reihenfolge der Änderungen vom längsten zum kürzesten. – revo