2017-06-27 3 views
0

Ich versuche, einen Weg zu finden, um festzustellen, ob eine Zeichenfolge mindestens n Anzahl von Zeichen in einer bestimmten Reihenfolge enthält.Regex mit fehlenden Zeichen

Ich verarbeite eine enorme Menge an Daten von Hand geschrieben und die Menge der Tippfehler ist ziemlich verrückt.

Ich muss Textteile in einer großen Zeichenfolge suchen so etwas wie finden:

irrelevant Text MONKEY, CHIMP: mehr irrelevant Text

I MONKEY, CHIMP finden müssen:

Die Art, wie dies falsch geschrieben ist, ist ziemlich verrückt. Hier ist ein extra seltsam Beispiel:

affe, schimpanse:

ich zu einem Punkt in meinem Regex habe, wo ich bin in der Lage alle diese Vorkommen zu finden. Wahrscheinlich nicht die schönste Lösung, aber hier ist es:

(m|M)(o|O)(n|N)(k|K)(e|E)(y|Y),?\s+(c|C)(h|H)(i|I)(m|M)(p|P)(\s+)?: 

Sieht ein bisschen komisch aus, aber es funktioniert.

Leider hört die Verrücktheit hier nicht auf. Ich muss diese Regex so ändern, dass es auch 1 fehlenden Buchstaben in jedem Wort erlaubt.

So würde ich brauche diese regex zu ändern, so dass es auch für so etwas wie funktionieren würde:

MONKEY, CIMP:

OnKey, Chimp:

OnKey, CIMP:

Ich würde denken, dass es eine Möglichkeit geben sollte, der Regex zu sagen, dass es Wordlength-1 genaue Anzahl von Zeichen benötigt, um zu entsprechen.

Gibt es eine einfache Möglichkeit, dies zu tun?

Ich habe in {4,} untersucht, aber ich bin mir nicht sicher, ob das die richtige Richtung ist oder ob es hier angewendet werden könnte.

Vielen Dank im Voraus, Peter

+1

setzen Sie können die Regex viel einfacher, wenn Sie den Text normalisieren, indem Sie es in Kleinbuchstaben zum Beispiel. – Markus

+2

Oder indem Sie eine Groß-/Kleinschreibung nicht beachten. Siehe https://stackoverflow.com/questions/3436118/is-java-regex-case-insensitive – GhostCat

+0

Regex allein reicht möglicherweise nicht für eine skalierbare Lösung. Sie könnten am Ende Ihren eigenen Parser benötigen, der Ähnlichkeiten mit einem Wörterbuchwort auswertet, z. mit einer Levenshtein Abstandsmetrik. – Mena

Antwort

0

^\ w {} # 10.10 $ ermöglichen Worte genau 10 Zeichen. Setzen Sie es auf Länge - 1. Dann machen Sie jedes der Zeichen optional.

Ich denke, nur {10} funktioniert auch.

+0

Sie können einfach '\ w {10}' schreiben; es ist nicht nötig, '\ w {10,10}' zu empfehlen. Dies beantwortet jedoch das Problem von OP nicht: Sie wollten ein Muster, das zum Beispiel auch "MonKEY, CIMp" - also ** 13 ** - Zeichen entspricht. –

+0

Deshalb habe ich geschrieben, dass dann jedes Zeichen optional gemacht werden sollte. Damit es weggelassen werden kann. – Gilrich

0

Sie können regex wie diese verwenden, ist dies nicht sehr schön, aber Ihr Beispiel ist zu seltsam

Erster Einsatz Groß- und Kleinschreibung :(https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#CASE_INSENSITIVE)

Ich weiß nicht, Lösung in einer Behandlung, aber Sie können zuerst für "m?o?n?k?e?y?\s+,?\s+c?h?i?m?p?(\s+)?:" überprüfen und dann in einem anderen Test für Länge, wird diese

+0

So Dinge wie fuzzy wie 'mon, p'willkommen? Klingt mir nicht sehr zuverlässig ... –

+0

@TomLord Erstmals vielen Dank für diesen so konstruktiven und nützlichen Kommentar. Dann habe ich, wie geschrieben, auch einen Test für die Länge hinzufügen können, und andere, wenn nötig, ich füge einfach die Struktur hinzu, die die Reihenfolge und die Möglichkeit, Buchstaben weniger zu haben, wenn Sie eine bessere Idee haben, klicken Sie einfach auf den blauen Button "Post Ihre Antwort " – azro

+0

StackOverflow hat meinen Kommentar gekürzt, so dass Sie vielleicht aufgrund der Formatierung missverstanden haben. Es sollen ** mehrere ** Leerzeichen auf beiden Seiten des Kommas sein - also wird die Längenprüfung immer noch bestehen. Sie können auch [meine Antwort] sehen (https: // stackoverflow.com/a/44783986/1954610) unten. –

1

Mit reinen Regex einfach sein, dann am besten Sie tun können, ist so etwas wie (Leerzeichen zur besseren Lesbarkeit hinzugefügt):

/ 
^
    (
    monkey\s*,?\s*chimp\s*: 
    | 
    onkey\s*,?\s*chimp\s*: 
    | 
    mnkey\s*,?\s*chimp\s*: 
    | 
    ... 
) 
    $ 
/ix 

Dies ist jedoch ein sehr langatmiger Ansatz und berücksichtigt immer noch nicht alle anderen Fuzzy-Treffer wie "Monkey, Chinp:" oder "Monkey; Chimp:".


Ein alternativer Ansatz Sie ist zu erste Überprüfung der Länge der Saite nehmen könnte:

/^\w{10,15}$/ 

und dann auf es einige sehr-Fuzzy-Match durchführen:

/m?o?n?k?e?y?\s*,?\s*c?h?i?m?p?\s*:/i 

Allerdings müssen Sie hier vorsichtig sein, da einige seltsame Ergebnisse in der Trefferliste enthalten sind, s uch als:

"mon  c:" 

würde ich empfehlen, der unter Verwendung eine Levenshtein Distance Bibliothek einen anderen, nicht-regex Ansatz. Dies ermöglicht es Ihnen, generische Grenzen auf ", wie eng die Zeichenfolge muss Monkey, Chimp"