24 votes

Fractionnement de la chaîne avec des conditions dans R

J'ai ceci mystring avec le délimiteur "_" . La condition ici est la suivante : s'il y a deux délimiteurs ou plus, je veux diviser au deuxième délimiteur et s'il n'y a qu'un seul délimiteur, je veux diviser à l'endroit où se trouve le premier délimiteur. ".Recal" et obtenir le result comme indiqué ci-dessous.

mystring<-c("MODY_60.2.ReCal.sort.bam","MODY_116.21_C4U.ReCal.sort.bam","MODY_116.3_C2RX-1-10.ReCal.sort.bam","MODY_116.4.ReCal.sort.bam")

résultat

"MODY_60.2"  "MODY_116.21" "MODY_116.3"  "MODY_116.4"

11voto

nongkrong Points 9204

Vous pouvez le faire en utilisant gsubfn

library(gsubfn)
f <- function(x,y,z) if (z=="_") y else strsplit(x, ".ReCal", fixed=T)[[1]][[1]]
gsubfn("([^_]+_[^_]+)(.).*", f, mystring, backref=2)
# [1] "MODY_60.2"   "MODY_116.21" "MODY_116.3"  "MODY_116.4" 

Cela permet de faire face aux cas où vous avez plus de deux "_", et que vous voulez séparer sur le deuxième, par exemple,

mystring<-c("MODY_60.2.ReCal.sort.bam",
            "MODY_116.21_C4U.ReCal.sort.bam",
            "MODY_116.3_C2RX-1-10.ReCal.sort.bam",
            "MODY_116.4.ReCal.sort.bam",
            "MODY_116.4_asdfsadf_1212_asfsdf",
            "MODY_116.5.ReCal_asdfsadf_1212_asfsdf",  # split by second "_", leaving ".ReCal"
            "MODY")

gsubfn("([^_]+_[^_]+)(.).*", f, mystring, backref=2)
# [1] "MODY_60.2"        "MODY_116.21"      "MODY_116.3"       "MODY_116.4"      
# [5] "MODY_116.4"       "MODY_116.5.ReCal" "MODY"            

Dans la fonction, f , x est la chaîne originale, y y z sont les prochaines correspondances. Donc, si z n'est pas un "_", alors il procède à la division par la chaîne alternative.

5voto

Pierre Lafortune Points 5107

Avec le stringr paquet :

str_extract(mystring, '.*?_.*?(?=_)|^.*?_.*(?=\\.ReCal)')
[1] "MODY_60.2" "MODY_116.21" "MODY_116.3" "MODY_116.4"

Il fonctionne également avec plus de deux délimiteurs.

5voto

hwnd Points 35496

Perl/PCRE dispose de l'option réinitialisation de la branche qui vous permet de réutiliser un numéro de groupe lorsque vous avez des groupes de capture dans différentes alternatives, et qui est considéré comme un seul groupe de capture.

IMO, cette fonctionnalité est élégante lorsque vous souhaitez fournir différentes alternatives.

x <- c('MODY_60.2.ReCal.sort.bam', 'MODY_116.21_C4U.ReCal.sort.bam', 
       'MODY_116.3_C2RX-1-10.ReCal.sort.bam', 'MODY_116.4.ReCal.sort.bam',
       'MODY_116.4_asdfsadf_1212_asfsdf', 'MODY_116.5.ReCal_asdfsadf_1212_asfsdf', 'MODY')

sub('^(?|([^_]*_[^_]*)_.*|(.*)\\.ReCal.*)$', '\\1', x, perl=T)
# [1] "MODY_60.2"        "MODY_116.21"      "MODY_116.3"       "MODY_116.4"      
# [5] "MODY_116.4"       "MODY_116.5.ReCal" "MODY"

4voto

Shenglin Chen Points 1101
gsub('^(.*\\.\\d+).*','\\1',mystring)
[1] "MODY_60.2"   "MODY_116.21" "MODY_116.3"  "MODY_116.4"

2voto

vks Points 35744
^([^_\\n]*_[^_\\n]*)(?:_.*|\\.ReCal[^_]*)$

Vous pouvez simplement le faire en utilisant gsub sans utiliser de regex complexe, il suffit de remplacer par \\1 Voir la démo.

https://regex101.com/r/wL4aB6/1

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X