2010-03-30 14 views
8

ich eine Eingabezeichenfolge haben, die ein Verzeichnis-Adresse lautet:Regular Expression Longest Mögliche Passende

Beispiel: ProgramFiles/Micro/Telephone

Und ich will es gegen eine Liste von Wörtern entsprechen sehr streng:

Beispiel: Tel|Tele|Telephone

Ich möchte mit Telephone und nicht Tel übereinstimmen. Gerade jetzt meine Regex sieht wie folgt aus:

my($output) = ($input =~ m/($list)/o); 

Die Regex oben gegen Tel übereinstimmen. Was kann ich tun, um es zu beheben?

+0

Platzieren Sie zuerst Ihr bevorzugtes Spiel? – eyelidlessness

+0

In welcher Sprache arbeiten Sie? – EsotericNonsense

+0

Es ist nicht immer möglich, die bevorzugte Übereinstimmung zuerst zu platzieren. Beispielsweise erzeuge ich derzeit eine Liste möglicher Keywords, die dem Konzept der "Flat Number" entsprechen. Meine Daten sind mehrsprachig und unordentlich. Ich könnte "Flt" oder "Apartment" oder "Apt" oder "Apartment Number" oder "Apartamento No" sehen ... Die Liste geht weiter! Der Versuch, einen regulären Ausdruck zu erstellen und aufrechtzuerhalten, der auf all diese Konzepte passt, bei denen alles in der richtigen Reihenfolge ist, ist praktisch praktisch unmöglich. – Nick

Antwort

9

Wenn Sie ein ganzes Wort Spiel wollen:

\b(Tel|Tele|Telephone)\b 

\b ist eine Null-Breite Wortgrenze. Wortgrenze bedeutet in diesem Fall den Übergang von oder zu einem Wortzeichen. Ein Wortzeichen (\w) ist [0-9a-zA-Z_].

Wenn Sie einfach gegen die längste in einem Teilwort übereinstimmen möchten, setzen Sie die längste zuerst. Zum Beispiel:

\b(Telephone|Tele|Tel) 

oder

(Telephone|Tele|Tel) 
+1

Meine Liste kann nicht garantiert werden, das längste Wort zuerst zu haben. – syker

+0

Die Wortgrenze funktioniert gedanklich. Aber ich kann der Argumentation nicht folgen, warum es funktioniert hat. – syker

+0

@syker Wenn Sie partielle Übereinstimmungen wünschen, ist der einfachste Weg, den Ausdruck zu konstruieren, die Wörterliste zu sortieren, die Reihenfolge umzukehren und dann alle Wörter mit '|' dazwischen zu verbinden, und das ergibt die richtige Reihenfolge großer Wörter mit kleineren Worttreffern. – cletus

2

Ändern der Aufträge: Tel|Tele|Telephone-Telephone|Tele|Tel. Durch den Regexp-Algorithmus wird der Wechsel von links nach rechts durchsucht, wenn dort eine Übereinstimmung gefunden wird, das ist es, kein gieriger Abgleich. Zum Beispiel:/a | ab | abc/arbeiten auf "abc" entspricht "a" statt der gierigsten "abc".

oder verwenden Sie die passenden Ausdrücke.

+0

Wie sicher ist es, sich auf dieses Verhalten zu verlassen? Ist es in der Regex-Spezifikation oder irgendwo irgendwo? Es wäre wirklich schön für mich, mich auf das '(XXX | XX | X)' -Formular für das, was ich implementiere, verlassen zu können – Hashbrown

-1

Wie wäre es mit dem Versuch, eine Übereinstimmung zu finden, solange die längste Übereinstimmung nicht irgendwo in der Eingabe ist? Etwas wie:

Finden Sie Telefon, oder finden Sie Tel, und Tele wo Telefon ist nicht irgendwo in der Eingabe. Also, beginnen sie wie ein regex aussehen zu lassen.

(Telefon) OR Zeichen ohne Telefon, gefolgt von (Tel | tele), gefolgt von Zeichen ohne Telefon

(Telefon | * (Telefon) {0 }. * (tel | tele). * (Telefon) {0}. *)

Macht das irgendeinen Sinn?