2008-10-16 8 views
6

Was verwende ich, um nach mehreren Wörtern in einer Zeichenfolge zu suchen? Ich möchte, dass die logische Operation AND ist, so dass alle Wörter irgendwo in der Zeichenkette sind. Ich habe eine Menge Unsinn-Absätze und einen einfachen englischen Absatz, und ich würde es gerne eingrenzen, indem ich ein paar gebräuchliche Wörter wie "das" und "und" vorschlage, aber ich möchte, dass es mit allen angegebenen Wörtern übereinstimmt.Regex Multi-Wortsuche

Antwort

2

Vielleicht ein language recognition chart mit Englisch zu erkennen, funktionieren würde. Einige schnelle Tests scheinen zu funktionieren (dies setzt Absätze voraus, die nur durch Zeilenumbrüche getrennt sind).

Die Regexp wird einer dieser Bedingungen entsprechen ... \ bword \ b ist Wort getrennt durch Grenzen Wort \ b ist eine Wortendung und nur Wort wird es an jeder Stelle des Absatzes übereinstimmen übereinstimmen.

+0

Ich würde nicht 'on' empfehlen, um Englisch zu erkennen. Es bedeutet "er" in vielen slawischen Sprachen (wie ich sicher bin, dass Vinko weiß;) –

+0

URL ist umgezogen: http://en.wikipedia.org/wiki/Wikipedia:Language_recognition_chart#English –

0

Angenommen, PCRE (Perl regexes), ich bin mir nicht sicher, dass Sie es überhaupt leicht tun können. Die UND-Operation ist eine Verkettung von Regexen, aber Sie möchten in der Lage sein, die Reihenfolge zu ändern, in der die Wörter erscheinen, ohne die Permutation formal generieren zu müssen. Für N Wörter, wenn N = 2, ist es erträglich; mit N = 3 ist es kaum in Ordnung; mit N> 3 ist es unwahrscheinlich, dass es akzeptabel ist. Also, die einfache iterative Lösung - N Regexes, eine für jedes Wort, und iterieren, um sicherzustellen, dass jeder erfüllt ist - sieht für mich wie die beste Wahl aus.

+0

Warum müssen die N Dinge jedoch regex sein? Könnte einfach "Index" hier verwenden. –

+1

\ b (foo | bar | baz) \ b. * \ B (?! \ 1) (foo | bar | baz) \ b. * \ B (?! \ 1) (?! \ 2) (foo | bar | baz) \ b sollte Permutationen behandeln, indem Rückreferenzen und negative Lookahead verwendet werden, um zu vermeiden, dass ein Wort zweimal abgeglichen wird. Es ist immer noch richtig böse, aber zumindest ist die Musterlänge nicht O (N!) – stevemegson

+0

@BKB: Ich bin nicht sicher, was Sie meinen, indem Sie einen Index verwenden. –

2

Erstens bin ich mir nicht sicher, was Sie zurückgeben wollen ... den ganzen Satz? Die Wörter zwischen deinen zwei gegebenen Wörtern?

Etwas wie:

\b(word1|word2)\b(\w+\b)*(word1|word2)\b(\w+\b)*\. 

(wo \b die Wortgrenze in Ihrer Sprache ist) würde einen vollständigen Satz übereinstimmen, die eine der beiden Wörter oder beides enthalten ..

Sie wahrscheinlich muss es Groß- und Kleinschreibung beachten, so dass, wenn es am Anfang des Satzes erscheint, es immer noch

+0

Passt das nicht nur zu einem Satz, der zwei Wörter enthält, entweder word1 gefolgt von word2 oder word2 gefolgt von word1 (wie gewünscht) oder word1 gefolgt von word1 oder word2 gefolgt von word2 (wie nicht gewünscht)? Das war das Problem, auf das ich stieß, wenn ich versuchte zu antworten. –

2

als Verkettung

übereinstimmen wird
^(?=.*?\b(?:word1)\b)(?=.*?\b(?:word2)\b)(?=.*?\b(?:word3)\b) 

OR als Wechsel

^(?=.*?\b(?:word1|word2|word3)\b 
^(?=.*?\b(?:word1)\b)|^(?=.*?\b(?:word2)\b)|^(?=.*?\b(?:word3)\b) 
11

Reguläre Ausdrücke unterstützen eine "Lookaround" -Bedingung, mit der Sie nach einem Begriff innerhalb einer Zeichenfolge suchen und dann die Position des Ergebnisses vergessen können. beginnend am Anfang der Zeichenfolge für den nächsten Suchbegriff. Dies ermöglicht das Suchen einer Zeichenfolge für eine Gruppe von Wörtern in beliebiger Reihenfolge.

Der reguläre Ausdruck dafür ist:

^(?=.*\bword1\b)(?=.*\bword2\b)(?=.*\bword3\b) 

Wo \b eine Wortgrenze ist und die ?= ist das Lookarounds Modifikator.

Wenn Sie eine variable Anzahl von Wörtern haben, nach denen Sie suchen möchten, müssen Sie diese reguläre Ausdruckszeichenfolge mit einer Schleife erstellen - umschließen Sie jedes Wort in der Lookaround-Syntax und hängen Sie es an den Ausdruck an.

+0

Genau was ich brauchte. Beachten Sie, dass oben ein paar Sternchen fehlen. Jeder Abschnitt sollte '(? =. * \ Bword \ b)' – Tamlyn

+0

Die Sternchen waren da, aber sie wurden als Markup behandelt. Ich habe es durch Anwendung der Codeformatierung behoben. –