web-dev-qa-db-fra.com

Extraire une correspondance d'expression régulière

J'essaie d'extraire un nombre d'une chaîne.

Et faites quelque chose comme [0-9]+ sur la chaîne "aaa12xxx" et obtenez "12".

Je pensais que ce serait quelque chose comme:

> grep("[0-9]+", "aaa12xxx", value=TRUE)
[1] "aaa12xxx"

Et puis j'ai pensé ... 

> sub("[0-9]+", "\\1", "aaa12xxx")
[1] "aaaxxx"

Mais j'ai eu une certaine forme de réponse à faire:

> sub("[0-9]+", "ARGH!", "aaa12xxx")
[1] "aaaARGH!xxx"

Il me manque un petit détail.

87
tovare

Utilisez le nouveau package stringr qui englobe toutes les expressions régulières existantes dans une syntaxe cohérente et en ajoute quelques-unes qui manquent:

library(stringr)
str_locate("aaa12xxx", "[0-9]+")
#      start end
# [1,]     4   5
str_extract("aaa12xxx", "[0-9]+")
# [1] "12"
139
hadley

Il est probablement un peu hâtif de dire ' ignore les fonctions standard ' - le fichier d'aide pour ?gsub fait même spécifiquement référence à 'Voir aussi':

‘Regmatches’ pour extraire les sous-chaînes appariées en fonction des résultats de «Regexpr», «gregexpr» et «regexec».

Donc, cela fonctionnera et est assez simple:

txt <- "aaa12xxx"
regmatches(txt,regexpr("[0-9]+",txt))
#[1] "12"
64
thelatemail

Peut être

gsub("[^0-9]", "", "aaa12xxxx")
# [1] "12"
22
Marek

Vous pouvez utiliser la correspondance paresseuse de Perl regexs:

> sub(".*?([0-9]+).*", "\\1", "aaa12xx99",Perl=TRUE)
[1] "12"

Essayer de remplacer les chiffres non numériques entraînera une erreur dans ce cas.

12

Utilisez les parenthèses de capture dans l'expression régulière et les références de groupe dans le remplacement. Tout ce qui est entre parenthèses est mémorisé. Ensuite, ils sont accédés par\2, le premier élément. La première barre oblique inverse échappe à l'interprétation de la barre oblique inverse dans R afin qu'elle soit transmise à l'analyseur d'expression régulière.

gsub('([[:alpha:]]+)([0-9]+)([[:alpha:]]+)', '\\2', "aaa12xxx")
4
Ragy Isaac

Utilisation de strapply dans le package gsubfn. strapply est similaire à apply en ce que les arguments sont object, modificateur et fonction, sauf que l'objet est un vecteur de chaînes (plutôt qu'un tableau) et que le modificateur est une expression régulière (plutôt qu'une marge):

library(gsubfn)
x <- c("xy13", "ab 12 cd 34 xy")
strapply(x, "\\d+", as.numeric)
# list(13, c(12, 34))

Ceci dit de faire correspondre un ou plusieurs chiffres (\ d +) dans chaque composant de x en passant chaque correspondance par as.numeric. Il retourne une liste dont les composants sont des vecteurs de correspondance des composants respectifs de x. En regardant la sortie, on voit que le premier composant de x a une correspondance qui est 13 et que le second composant de x a deux correspondances qui sont 12 et 34. Voir http://gsubfn.googlecode.com pour plus d'informations .

2
G. Grothendieck

Une façon serait la suivante: 

test <- regexpr("[0-9]+","aaa12456xxx")

Maintenant, notez que regexpr vous donne les index de début et de fin de la chaîne:

    > test
[1] 4
attr(,"match.length")
[1] 5

Vous pouvez donc utiliser cette information avec la fonction substr

substr("aaa12456xxx",test,test+attr(test,"match.length")-1)

Je suis sûr qu'il existe un moyen plus élégant de faire cela, mais c'était le moyen le plus rapide que j'ai pu trouver. Alternativement, vous pouvez utiliser sub/gsub pour supprimer ce que vous ne voulez pas laisser ce que vous voulez. 

2
Robert

Une autre solution:

temp = regexpr('\\d', "aaa12xxx");
substr("aaa12xxx", temp[1], temp[1]+attr(temp,"match.length")[1])
1
pari

Une différence importante entre ces approches est le comportement des non-correspondances. Par exemple, la méthode regmatches peut ne pas renvoyer une chaîne de même longueur que l'entrée s'il n'y a pas de correspondance dans toutes les positions.

> txt <- c("aaa12xxx","xyz")

> regmatches(txt,regexpr("[0-9]+",txt)) # could cause problems

[1] "12"

> gsub("[^0-9]", "", txt)

[1] "12" ""  

> str_extract(txt, "[0-9]+")

[1] "12" NA  
0
andyyy