2017-07-12 3 views
4

Ich habe eine Unicode-Datei mit einem (schwedischen) Wikipedia-Artikel in MediaText Markup. Ich möchte es von allen Auszeichnungen säubern. In bestimmten Fällen möchte ich Text aus den Markup-Tags extrahieren, z. B. die Hyperlinks von Hyperlinks (z. B. eine vereinfachte wikiextractor).Wie finden und ersetzen Unicode-Zeichen in Haskell?

Mein Ansatz besteht darin, eine Reihe von Regexes über die Datei auszuführen, um Markup zu entfernen. Im Link-Beispiel muss ich [[link]] durch link ersetzen. Es gelingt mir, dies gut mit einer Regex zu beheben, solange der Text keine Unicode-Zeichen wie ö enthält.

Beispiel von dem, was ich versucht habe:

ghci> :m +Data.Text 
ghci> subRegex (mkRegex "\\[\\[([() a-zA-Z]*)\\]\\]") "Se mer om [[Stockholm]]" "\\1" 
"Se mer om Stockholm" 
ghci> subRegex (mkRegex "\\[\\[([() a-zA-Z]*)\\]\\]") "Se mer om [[Göteborg]]" "\\1" 
"Se mer om [[G\246teborg]]" 

Warum funktioniert das nicht? Wie kann ich der Regex-Engine klar machen, dass ö tatsächlich ein normaler Brief ist (zumindest auf Schwedisch)?

Bearbeiten: Das Problem scheint nicht wirklich im Muster zu sitzen, aber in der Maschine. Wenn ich alle Zeichen außer im Linktext erlaube, könnte man erwarten, dass ö erlaubt ist. Aber nicht so ...

ghci> subRegex (mkRegex "\\[\\[([^q]*)\\]\\]") "[[Goteborg]]" "\\1" 
"Goteborg" 
ghci> subRegex (mkRegex "\\[\\[([^q]*)\\]\\]") "[[Göteborg]]" "\\1" 
"[[G\246teborg]]" 
ghci> subRegex (mkRegex "ö") "ö" "q" 
"q" 
ghci> subRegex (mkRegex "[ö]") "ö" "q" 
"\246" 

Das Problem scheint speziell bei der Verwendung von Zeichenklassen auftreten. Es passt ö gut für sich.

+0

Welche Bibliotheken verwenden Sie? Deine Göteborg Regexes geben mir 'ReturnCode 17, 'illegale Bytefolge', wenn ich sie versuche. In jedem Fall sagt die [POSIX Regex-Spezifikation] (http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09): "Matching [ist] basierend auf dem Bitmuster, das zum Codieren des Zeichens verwendet wird. ... [I] fa Zeichensatz enthält zwei oder mehr Codierungen für ein Grafiksymbol ... Es wird nicht versucht, nach einer anderen Darstellung des codierten Symbols zu suchen.Wenn dies erforderlich ist, ... geben Sie Äquivalenzklassen an, die alle Varianten von das Symbol." Vielleicht ist es das? –

+0

Ich habe die Bibliothek 'regex-compat' verwendet, die die Funktion' subRegex' enthält. Ich habe schwedische Tastatureinstellungen auf meinem Ubuntu. Sie können sehen, dass Haskell es korrekt als Unicode-Punkt 246 erkannt hat. Ich würde nicht erwarten, dass Zeichenklassen das Problem sind, da das negierte Char-Klassen-Muster auch nicht funktioniert. – LudvigH

Antwort

1

Ich habe mich jetzt entschieden, mit Text.Regex.PCRE.Heavy zu gehen, wie in diesem SO Answer des Autors vorgeschlagen. Es löst mein Problem.

Somit wird die Lösung

GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help 
Prelude> :m Text.Regex.PCRE.Heavy 
Prelude Text.Regex.PCRE.Heavy> :set -XFlexibleContexts 
Prelude Text.Regex.PCRE.Heavy> :set -XQuasiQuotes 
Prelude Text.Regex.PCRE.Heavy> gsub [re|\[\[([^\]]*)\]\]|] (\(firstMatch:_) -> firstMatch :: String) "[[Göteborg]]" :: String 
"G\246teborg" 

Leider, warum ich immer noch nicht weiß der POSIX-Backend nicht damit umgehen kann, aber das Backend kann PCRE.