2017-05-09 2 views
3

Ich versuche, eine Datenrahmen-String-Substitution in R durchzuführen. Ich muss alle Wörter finden, denen '@' vorausgeht (ohne Leerzeichen, z. B. @word) und ändern ' zum '!' (z.B. von @word zu! word). Gleichzeitig bleiben die anderen Instanzen von '@' (z. B. @ oder @@ oder @ [@]) intakt. Zum Beispiel ist dies mein ursprünglicher Datenrahmen (zu ändern: @dEF, @jkl, @stu):Ersatzwort mit gleichem Wort ohne initial @ in R

> df = data.frame(number = 1:4, text = c('abc @def ghi', '@jkl @ mno', '@[@] pqr @stu', 'vwx @@@ yz')) 
> df 
    number   text 
1  1 abc @def ghi 
2  2 @jkl @ mno 
3  3 @[@] pqr @stu 
4  4 vwx @@@ yz 

Und das ist, was ich brauche es aussehen:

> df_result = data.frame(number = 1:4, text = c('abc !def ghi', '!jkl @ mno', '@[@] pqr !stu', 'vwx @@@ yz')) 
> df_result 
    number   text 
1  1 abc !def ghi 
2  2 !jkl @ mno 
3  3 @[@] pqr !stu 
4  4 vwx @@@ yz 

ich versucht habe, mit

> gsub('@.+[a-z] ', '!', df$text) 
[1] "abc !ghi" "[email protected] mno"  "[email protected]"  "vwx @@@ yz" 

Aber das Ergebnis ist nicht das gewünschte. Jede Hilfe wird sehr geschätzt.

Vielen Dank.

Antwort

3

Wie wäre es

gsub("(^|)@(\\w)", "\\1!\\2", df$text) 
# [1] "abc !def ghi" "!jkl @ mno" "@[@] pqr !stu" "vwx @@@ yz" 

Dies entspricht einem @ Symbol am Anfang einer Zeichenkette oder nach einem Raum. Dann erfassen wir das Wortzeichen nach dem @-Symbol und ersetzen @ durch !.

Erklärung mit freundlicher Genehmigung von regex101.com:

  • (^|) ist die erste Capturing-Gruppe; ^ bestätigt die Position am Anfang der Zeichenfolge; | bezeichnet "oder"; Leerzeichen passt das Leerzeichen buchstäblich
  • @ den Charakter passt @ wahrsten Sinne des Wortes (Groß- und Kleinschreibung)
  • (\\w) ist die 2. Capturing-Gruppe, bezeichnet es ein Wortzeichen

Der Ersatz-String \\1!\\2 den regulären Ausdruck ersetzt mit der ersten Erfassungsgruppe (\\1), gefolgt von !, gefolgt von der zweiten Erfassungsgruppe (\\2).

+0

Hallo Rich Scriven, vielen Dank für die Lösung und eine sehr detaillierte Erklärung der Logik dahinter. Es funktioniert perfekt. Ich wünsche ihnen einen wunderbaren Tag. – user3550647

3

können Sie eine positive Vorschau (?=...)

gsub("@(?=[A-Za-z])", "!", df$text, perl = TRUE) 
[1] "abc !def ghi" "!jkl @ mno" "@[@] pqr !stu" "vwx @@@ yz" 

aus der Nutzung Dokumentationsseite "Reguläre Ausdrücke wie in R verwendet":

Patterns (? = ...) und (?!. ..) sind positive und negative Lookahead-Assertionen mit einer Breite von Null: Sie passen zusammen, wenn ein Versuch, den ... Forward von der aktuellen Position aus zu erreichen, Erfolg haben würde (oder nicht), aber keine Zeichen in der zu verarbeitenden Zeichenkette verbrauchen.

+0

Hallo Sraffa, vielen Dank für deine Antwort und die Erklärung. Ihre Lösung funktioniert perfekt. Haben Sie einen guten Tag. – user3550647