2017-04-08 12 views
1

Ich habe eine Zeichenfolge mit alphanumerischen Zeichen, Sonderzeichen und nicht UTF-8 Zeichen. Ich möchte die speziellen und nicht utf-8 Zeichen entfernen.behalten Sie nur alphanumerische Zeichen und Leerzeichen in einem String mit gsub

Hier ist, was ich versucht habe:

gsub('[^0-9a-z\\s]','',"�+ Sample string here =�{�>E�BH�P<]�{�>") 

jedoch Dies entfernt die Sonderzeichen (Interpunktion + nicht UTF-8), aber der Ausgang hat keine Räume.

gsub('/[^0-9a-z\\s]/i','',"�+ Sample string here =�{�>E�BH�P<]�{�>") 

Das Ergebnis hat Leerzeichen, aber es sind immer noch nicht utf8 Zeichen vorhanden.

Irgendwelche Arbeiten herum?

Für die Probe Zeichenfolge oben ausgegeben werden soll: Beispiel Zeichenfolge hier

+0

Wollten Sie 'trimws (gsub ('[^ 0-9A-Za-z]', '',"? "+ Sample string here =? E? ½BH? P <]? (?>)) ' – akrun

+1

' [^ A-z0-9] 'ist prägnanter @akrun. Allerdings bleibt "Sample String hier EBHP" – zacdav

+3

'[A-z]' passt nicht nur Buchstaben. –

Antwort

3

Sie könnten die Klassen verwenden [:alnum:] und [:space:] dafür:

sample_string <- "�+ Sample 2 string here =�{�>E�BH�P<]�{�>" 
gsub("[^[:alnum:][:space:]]","",sample_string) 
#> [1] "ï Sample 2 string here ïïEïBHïPïï" 

Alternativ Sie können PCRE-Codes verwenden, um auf bestimmte Zeichensätze zu verweisen:

gsub("[^\\p{L}0-9\\s]","",sample_string, perl = TRUE) 
#> [1] "ï Sample 2 string here ïïEïBHïPïï" 

In beiden Fällen wird deutlich, dass die noch vorhandenen Buchstaben als Buchstaben gelten. Auch die EBHP-Inneren sind immer noch Buchstaben, daher ist der Zustand, in dem Sie ersetzen, nicht korrekt. Sie wollen nicht alle Buchstaben zu halten, Sie wollen einfach nur von A-Z zu halten, a-z und 0-9:

gsub("[^A-Za-z0-9 ]","",sample_string) 
#> [1] " Sample 2 string here EBHP" 

Dieses noch die EBHP enthält. Wenn Sie wirklich nur einen Abschnitt halten möchten, die nur Buchstaben und Zahlen enthält, sollten Sie die umgekehrte Logik verwenden: Wählen Sie, was Sie wollen und ersetzen Sie alles aber, dass die Verwendung von Rückreferenzierungen:

gsub(".*?([A-Za-z0-9 ]+)\\s.*","\\1", sample_string) 
#> [1] " Sample 2 string here " 

Oder, wenn Sie einen finden wollen String, auch nicht durch Leerzeichen gebunden, verwenden Sie die Wortgrenze \\b statt:

gsub(".*?(\\b[A-Za-z0-9 ]+\\b).*","\\1", sample_string) 
#> [1] "Sample 2 string here" 

Was hier passiert:

  • .*? passt überhaupt etwas lea (.) st 0 mal (*) aber nicht gierig (?). Dies bedeutet, dass gsub versuchen wird, die kleinste mögliche Anzahl von Stücken zu passen.
  • alles zwischen () gespeichert wird und kann durch \\1 im Ersatz refered werden
  • \\b zeigt eine Wortgrenze
  • Dieses mindestens einmal folgt (+) von jedem Charakter, ist AZ, az, 0-9 oder ein Leerzeichen.Sie müssen es so machen, weil die speziellen Buchstaben zwischen der Groß- und Kleinschreibung in der Codetabelle enthalten sind. So verwendet A-z alle Sonderzeichen (die UTF-8 BTW sind!)
  • nach dieser Sequenz, passen Sie alles mindestens Null mal, um den Rest der Zeichenfolge zu entfernen.
  • die Rückreferenz \\1 in Verbindung mit .* in der Regex, wird sicherstellen, dass nur der erforderliche Teil in der Ausgabe bleibt.
+0

fügen Sie 'trimws()' der Vollständigkeit halber hinzu. Beachten Sie, dass dies nur funktioniert, weil die Zeichenfolge durch Leerzeichen begrenzt ist und nicht 100% funktioniert, es sei denn, das ist wahr. – zacdav

+0

@zacdav oder einfach nicht die Leerzeichen im Endergebnis behalten. –

+1

@zacdav Ihre Bemerkung über die Leerzeichen ist korrekt, also habe ich ein Beispiel mit Wortgrenzen hinzugefügt. –

0

stringr eine differ Regex-Engine verwenden, die Klassen POSIX-Zeichen unterstützt. Das: ascii: Benennt die Klasse, die im Allgemeinen in eckigen Klammern eingeschlossen werden muss [: asciii:], innerhalb der äußeren eckigen Klammer. Das [^ zeigt die Negation der Übereinstimmung an.

library(stringr) 
str_replace_all("�+ Sample string here =�{�>E�BH�P<]�{�>", "[^[:ascii:]]", "") 

Ergebnis in [1] "+ Beispiel Zeichenfolge hier = {> EBHP <] {>"

Verwandte Themen