2016-06-20 9 views
1

Gibt es eine Möglichkeit, Fuzzy Regex Matching in Julia zu tun?Fuzzy Regex Matching in Julia

Ich habe den folgenden regulären Ausdruck Test konstruiert:

toMatch = Regex(word,"i") 
ismatch(toMatch,input_string) 

Ich mag wäre in der Lage sein, diesen Test zu tun, aber für einen gewissen Spielraum in der Anpassung zu ermöglichen und diese durch Levenshtein Abstand zu spezifizieren.

Ich habe das Paket Levenshtein gefunden, das die Entfernung berechnen kann, bin mir aber nicht sicher, wie man es in diese Logik einbaut. Zum Beispiel:

levenshtein("hello","hllo")` 
> 1 
+0

Benötigen Sie Regex hier? Das klingt nach einem harten (rechnerischen) Problem für allgemeine reguläre Ausdrücke. –

+0

Es ist möglich, dass ich es nicht brauche. Ich habe zuerst dieses Problem für exakte Übereinstimmungen mit dem hier aufgelisteten Code gelöst und versuche jetzt, Rechtschreibfehler innerhalb von ** input_string ** zu akzeptieren. – Aaron

Antwort

0

(Diese Antwort hat nichts mit regulären Ausdrücken zu tun, aber es deckt einige Anwendungsfälle.)

Ich weiß nicht, ob dies für Ihren Anwendungsfall funktioniert. Aber es sieht so aus, als ob Sie versuchen, herauszufinden, ob ein Wort (oder ein falscher Rechtschreibfehler) in Ihrem Text enthalten ist. Wenn der Text durch Leerzeichen getrennt, und Ihr Wort keine Leerzeichen enthält, könnten Sie versuchen, so etwas wie:

nopunct(s) = filter(c -> !ispunct(c), s) 
nfcl(s) = normalize_string(s, decompose=true, compat=true, casefold=true, 
           stripmark=true, stripignore=true) 
canonicalize(s) = nopunct(nfcl(s)) 
fuzzy(needle, haystack, n) = any(
    w -> levenshtein(w, canonicalize(needle)) < n, 
    split(canonicalize(haystack))) 

Was das bedeutet ist, etwa:

nfcl Saiten mit ähnlichen „menschlichen“ Erscheinungen normalisieren, indem Sie Akzente entfernen, den Fall ignorieren und die Unicode-Normalisierung durchführen. Das ist ziemlich nützlich für die Fuzzy Matching:

julia> nfcl("Ce texte est en français.") 
"ce texte est en francais." 

nopunct Streifen Satzzeichen, weiter die Zeichenfolge zu vereinfachen.

julia> nopunct("Hello, World!") 
"Hello World" 

canonicalize verbindet einfach diese beiden Transformationen.

Dann überprüfen wir, ob eines der Wörter im Heuhaufen (durch Leerzeichen getrennt) innerhalb n der Nadel sind.

Beispiele:

julia> fuzzy("Robert", "My name is robrt.", 2) 
true 

julia> fuzzy("Robert", "My name is john.", 2) 
false 

Dies ist keineswegs eine vollständige Lösung bedeutet, aber es deckt viele gemeinsame Fällen Gebrauch. Für erweiterte Anwendungsfälle sollten Sie sich genauer mit the subject befassen.

+0

Dies ist sehr hilfreich, aber in meinem Fall kann das Wort, das ich in meinem Text finde, Leerzeichen enthalten, da es sich um eine Phrase handeln könnte. Gibt es irgendwelche Änderungen, die Sie vielleicht anpassen könnten? – Aaron

+0

@Aaron Wenn die Nadel eine einfache alte Zeichenfolge ist (keine Regex-Zeichen wie '*' oder '()'), gibt es einen "Trick", den Sie tun können: Berechnen Sie 'levenshtein (Nadel, Heuhaufen)' und prüfen Sie, ob dies der Fall ist weniger als 'Länge (Heuhaufen) - Länge (Nadel) + n'. (Mindestens 'Länge (Heuhaufen) - Länge (Nadel)' Zeichen müssen gelöscht werden, um vom Heuhaufen zur Nadel zu kommen, dann möglicherweise bis zu 'n' weiteren Operationen.) Dies funktioniert unabhängig davon, welche Zeichen in der Nadel sind. –

+0

Ich denke, das wird für meine Bedürfnisse sehr gut funktionieren. Eine Modifikation, die ich hinzufügen werde, ist, "n" geringfügig als eine Funktion der "Länge der Nadel" zu variieren. – Aaron