2016-08-08 15 views
0

Lässt sich auf einer exemple aussehen:Erste 2 Substrings/Gruppen vor und nach der letzten n-ten "_"

abc_def_ghi_jkl 

Wenn ich n = 1 wählen, möchte ich die Ausgabe sein:

group1 = abc_def_ghi 
group2 = jkl 

Wenn ich wählen n = 2 ich die Ausgabe sein wollen:

group1 = abc_def 
group2 = ghi_jkl 

Hinweis

Die _, die die zwei Gruppen getrennt hat, wird entfernt.

Vorerst Ich dachte nur, wie die letzte Gruppe zu wählen, sondern auch wählt die _:

(?:.(?!(?=\_)))+$ 

Note2 ich zur Zeit auf dem regex Teil bin konzentriert, aber es ist ein Code verwendet werden, in R wenn es hilft, zu einer Lösung zu kommen.

+1

Gibt es einen bestimmten Grund regex zu benutzen? Für mich ist die Verwendung von 'strsplit' auf' _ _ 'gefolgt von' paste (..., collapse = '_') 'eine einfachere Lösung, um dieses spezielle Beispiel zu lösen. – Vandenman

+0

So einfach ... 3 Stunden, dass ich das Problem falsch anschaue. Vielen Dank ! Ich bin immer noch neugierig, aber lernen Sie mehr über Regex, wenn jemand die Antwort hat :) –

+1

Nun, es kann eine Regex-basierte Antwort mit dem Abgleich der Gruppen, wie ['^ (. *?) _ ((?: _) ? [^ _] +) {3}) $ '] (https://regex101.com/r/rW0sE8/1). Ersetzen Sie die Zahl in '{...}', um die benötigten Teile zu erhalten. Gerade wenn Sie eine Zahl außerhalb des Bereichs verwenden, kann das Verhalten merkwürdig werden. –

Antwort

1

Eine Möglichkeit, auf den n-te Auftreten von _ vom Ende des Strings aufgeteilt:

strsplit("abc_def_ghi_jkl", "_(?=([^_]*_){0}[^_]*$)", perl = T) 
            # ^
            # you can modify the quantifier here 
#[[1]]           
#[1] "abc_def_ghi" "jkl"     # split on the 1st 

strsplit("abc_def_ghi_jkl", "_(?=([^_]*_){1}[^_]*$)", perl = T) 
#[[1]] 
#[1] "abc_def" "ghi_jkl"     # split on the 2nd 

strsplit("abc_def_ghi_jkl", "_(?=([^_]*_){2}[^_]*$)", perl = T) 
#[[1]] 
#[1] "abc"   "def_ghi_jkl"   # split on the 3rd 

_(?=([^_]*_){2}[^_]*$) sucht nach _ vor dem Muster ([^_]*_){2}[^_]*$ über ?= vorausschauen Syntax und das Muster beginnt mit dem Ende der Zeichenfolge $ und überspringt alle nicht _ Muster [^_]* und entspricht ([^_]*_) für bestimmte Anzahl von Vorkommen und danach auf die angegebene _ aufgeteilt.

aktualisieren mit str_match von stringr Paket:

str_match("abc_def_ghi_jkl", "(.*)_((?:[^_]*_){0}[^_]*$)")[,2:3] 
# [1] "abc_def_ghi" "jkl"  

str_match("abc_def_ghi_jkl", "(.*)_((?:[^_]*_){1}[^_]*$)")[,2:3] 
# [1] "abc_def" "ghi_jkl" 

str_match("abc_def_ghi_jkl", "(.*)_((?:[^_]*_){2}[^_]*$)")[,2:3] 
# [1] "abc"   "def_ghi_jkl"