2016-10-04 1 views
0

Ich habe ein Array von Phrasen und versuche herauszufinden, ob eine Textzeichenfolge eine vollständige Phrase enthält. Ich bin derzeit mit dem folgenden regulären Ausdruck:JS Regex: Liste der Phrasen genau (einschließlich der Hash-Symbole)

var arrOfWords = ['foo', 'bar', 'foo bar'] 
var regEx = new RegExp('\\b(' + arrOfWords.join('|') + ')\\b', 'gi') 

console.log(regEx) 
/\b(foo|bar|foo bar)\b/gi 

I \b verwendet, weil ich nicht Strings enthalten wollte, sondern das komplette Wort/Phrase, dh „foo“ sollte nicht mit „foobar“, passen aber entsprechen sollte: „ich foo gefallen“

Dies funktioniert gut, aber Wortgrenzen, \b, ignorieren Phrasen, die mit # beginnen, wie \b die Grenze bei alphanumerischen Zeichen beginnt.

Also, wenn „#Hashtag“ im Array ist, wird es nur passen, wenn die Zeichenfolge getestet wird, hat „Hashtag“, nicht „#Hashtag“

Was ich wirklich bin auf der Suche nach wäre ein regulärer Ausdruck, dass entspricht der gesamten im Array angegebenen Phrase, einschließlich Symbolen und Hashes. Oder vielleicht eine Lösung, die das umgehen kann.

Kann mir jemand in die richtige Richtung zeigen? Vielen Dank.

Antwort

1

Leider hat JS kein Lookbehind, daher ist es unmöglich, auf Eigenschaften des vorherigen Zeichens zu passen, ohne dieses Zeichen in die Übereinstimmung einzubeziehen (außer durch \b, was, wie Sie anmerken, sehr begrenzt ist). Wenn dies für Sie akzeptabel ist, können Sie:

/(?:^|\W)(foo|bar|foo bar|#hashtag)(?=$|\W)/ 

und nur mit der ersten Erfassungsgruppe befassen. Dies ist garantiert nicht überlappen, wenn Sie nur vollständige Wörter/Phrasen wollen, da es garantiert ein Nicht-Wort-Trennzeichen ist.

Hinweis: Wenn arrOfWords Zeichenketten mit regexp-aussagekräftigen Zeichen enthält, werden sie als solche interpretiert; So wird foo.bar übereinstimmen foosbar. Lesen Sie here darüber, wie Sie dies vermeiden können.

Hey, das sind 90% für mich, danke. Nur um zu nitpick, bemerkte ich, dass, wenn arrOfWords#hashtag enthält, wird es mit ##hashtag in der Zeichenfolge übereinstimmen. Gibt es eine Möglichkeit, nur zu vergleichen, wenn die Anzahl der Hashwerte genau ist?

Dann müssen Sie explizit sein, was ein Wort und was ein Nicht-Wort-Zeichen ist, und ersetzen \W damit.

/(?:^|[^\w#'-])(foo|bar|foo bar|#hashtag)(?=$|[^\w#'-])/ 
+0

Hey, das sind 90% für mich, danke. Nur um zu nitpick, bemerkte ich, dass, wenn 'arrOfWords' '# hashtag' enthält, es mit '## hashtag' in der Zeichenfolge übereinstimmt. Gibt es eine Möglichkeit, nur zu vergleichen, wenn die Anzahl der Hashwerte genau ist? –

+0

Sieht so aus, als müssten Sie '/ (?:^| \ S) (foo | bar | foo bar | #hashtag) (? = $ | \ S) /' –

+0

@ WiktorStribiżew: Das ist vielleicht nicht zu restriktiv (und nur OP kann es sagen). Zum Beispiel "Eleanor sagte" #hashtag ist trending "' würde nicht mit Ihrem, aber würde mit mir zusammenpassen. – Amadan

Verwandte Themen