wake-up-neo.net

R: So ersetzen Sie Leerzeichen ('') in einem String mit einem * einfachen * Backslash und Leerzeichen ('\')

Ich habe oft gesucht und habe die Antwort hier oder anderswo nicht gefunden. Ich möchte jeden Platz ' ' in Variablen, die Dateinamen enthalten, durch einen '\ ' ersetzen. (Ein Anwendungsfall könnte sich auf Shell-Befehle beziehen, wobei die Leerzeichen mit Escapezeichen versehen sind, sodass jeder Dateiname nicht als Liste von Argumenten angezeigt wird.) Ich habe die StackOverflow-Frage "durchforsten, um einen einzelnen Backslash in R zu ersetzen" . und finden Sie heraus, dass viele Kombinationen wie angegeben funktionieren:

> gsub(" ", "\\\\", "a b")
[1] "a\\b"

> gsub(" ", "\\ ", "a b", fixed = TRUE)
[1] "a\\ b"

versuchen Sie diese jedoch mit einer Version mit einem Schrägstrich, und R ignoriert sie:

> gsub(" ", "\\ ", "a b")
[1] "a b"

> gsub(" ", "\ ", "a b", fixed = TRUE)
[1] "a b"

Für den Fall in die entgegengesetzte Richtung - das Entfernen von Schrägstrichen aus einer Zeichenfolge funktioniert für zwei:

> gsub("\\\\", " ", "a\\b")
[1] "a b"

> gsub("\\", " ", "a\\b", fixed = TRUE)
[1] "a b"

Bei einzelnen Schrägstrichen hindert mich eine gewisse innere Perversität in R jedoch sogar daran, sie zu entfernen:

> gsub("\\", " ", "a\\b")
Error in gsub("\\", " ", "a\\b") : 
  invalid regular expression '\', reason 'Trailing backslash'

> gsub("\", " ", "a\b", fixed = TRUE)
Error: unexpected string constant in "gsub("\", " ", ""

Der "ungültige reguläre Ausdruck" sagt uns etwas, aber ich sehe nicht was. (Beachten Sie auch, dass die Perl = True-Option nicht hilft.)

Selbst bei drei hinteren Schrägstrichen bemerkt R nicht einmal einen:

> gsub(" ", "\\\ ", "a b")
[1] "a b"

Das Muster erstreckt sich auch! Sogar ein Vielfaches von zwei Arbeiten:

> gsub(" ", "\\\\\\\\", "a b")
[1] "a\\\\b"

aber nicht ungerade Vielfache (sollte '\\\ ' erhalten:

> gsub(" ", "\\\\\\ ", "a b")
[1] "a\\ b"

> gsub(" ", "\\\ ", "a b", fixed = TRUE)
[1] "a\\ b"

(Ich würde 3 Schrägstriche erwarten, nicht zwei.)

Meine zwei Fragen sind:

  • Wie kann mein Ziel, einen ' ' durch einen '\ ' zu ersetzen, erreicht werden?
  • Warum sind die ungeraden Zahl-Slash-Varianten der Ersetzungen fehlgeschlagen, während die Ersetzung der geraden Zahl-Slash funktioniert hat?

Für Shell-Befehle besteht eine einfache Lösung darin, die Dateinamen zu zitieren, aber ein Teil meines Interesses besteht einfach darin, zu verstehen, was mit der Regex-Engine von R los ist.

9
user3897315

Machen Sie sich bereit für ein Face-Palm, weil dies:

> gsub(" ", "\\\ ", "a b", fixed = TRUE)
[1] "a\\ b"

arbeitet eigentlich.

Bei den beiden umgekehrten Schrägstrichen handelt es sich nur um die Art der R-Konsole, einen einzelnen umgekehrten Schrägstrich anzuzeigen, der beim Drucken auf dem Bildschirm nicht angezeigt wird.

Um zu bestätigen, dass der Austausch mit einem einzelnen Backslash tatsächlich funktioniert, versuchen Sie, die Ausgabe in eine Textdatei zu schreiben, und prüfen Sie sich selbst:

f <- file("C:\\output.txt")
writeLines(gsub(" ", "\\", "a b", fixed = TRUE), f)
close(f)

In output.txt sollten Sie Folgendes sehen:

a\b
13
Tim Biegeleisen

Sehr hilfreiche Diskussion! (Ich habe den Teufel schon seit 2 Tagen gegoogelt.)

Eine andere Möglichkeit, den Unterschied zu erkennen (anstatt in eine Datei zu schreiben), besteht darin, den Inhalt der Zeichenfolge mithilfe von print und cat zu vergleichen.

z <- gsub(" ", "\\", "a b", fixed = TRUE)

> print(z)
[1] "a\\ b"

> cat(z)
a\ b

Indem wir cat anstelle von print verwenden, können wir bestätigen, dass die gsub-Zeile das tut, was beabsichtigt ist, wenn wir versuchen, einem String einzelne Backslashes hinzuzufügen.

0
D. Woods