Question

R, est-il possible d'extraire la capture du groupe à partir d'une expression régulière? Pour autant que je sache, aucun des grep, grepl, regexpr, gregexpr, sub ou gsub retourner le groupe capture.

Je dois extraire paires clé-valeur de chaînes qui sont encodées ainsi:

\((.*?) :: (0\.[0-9]+)\)

Je peux toujours juste faire plusieurs greps-match complet, ou faire en dehors de traitement (non-R), mais j'espérais que je peux le faire tout dans R. Est-il y a une fonction ou d'un package qui fournit une telle fonction faire?

Était-ce utile?

La solution

str_match(), à partir du package stringr , va faire . Elle renvoie une matrice de caractères avec une colonne pour chaque groupe lors de la rencontre (et une pour l'ensemble du match):

> s = c("(sometext :: 0.1231313213)", "(moretext :: 0.111222)")
> str_match(s, "\\((.*?) :: (0\\.[0-9]+)\\)")
     [,1]                         [,2]       [,3]          
[1,] "(sometext :: 0.1231313213)" "sometext" "0.1231313213"
[2,] "(moretext :: 0.111222)"     "moretext" "0.111222"    

Autres conseils

gsub fait cela, votre exemple:

gsub("\\((.*?) :: (0\\.[0-9]+)\\)","\\1 \\2", "(sometext :: 0.1231313213)")
[1] "sometext 0.1231313213"

vous devez échapper à la \ s dans les citations puis ils travaillent pour le regex.

Hope this helps.

Essayez regmatches() et regexec():

regmatches("(sometext :: 0.1231313213)",regexec("\\((.*?) :: (0\\.[0-9]+)\\)","(sometext :: 0.1231313213)"))
[[1]]
[1] "(sometext :: 0.1231313213)" "sometext"                   "0.1231313213"

gsub () peut le faire et revenir seul le groupe de capture:

Cependant, pour que cela fonctionne, vous devez explicitement sélectionner des éléments en dehors de votre groupe de capture comme mentionné dans l'aide gsub ().

  

(...) des éléments de vecteurs de caractères x »qui ne sont pas substitués sera retourné inchangé.

Donc, si votre texte à sélectionner réside dans le milieu d'une chaîne, en ajoutant. * Avant et après que le groupe de capture devrait vous permettre de revenir seulement elle.

gsub(".*\\((.*?) :: (0\\.[0-9]+)\\).*","\\1 \\2", "(sometext :: 0.1231313213)") [1] "sometext 0.1231313213"

J'aime PCRE. Probablement le fait que quelqu'un d'autre aussi ...

Voici une fonction qui fait des expressions régulières compatibles Perl et correspond à la fonctionnalité des fonctions dans d'autres langues que je suis habitué:

regexpr_perl <- function(expr, str) {
  match <- regexpr(expr, str, perl=T)
  matches <- character(0)
  if (attr(match, 'match.length') >= 0) {
    capture_start <- attr(match, 'capture.start')
    capture_length <- attr(match, 'capture.length')
    total_matches <- 1 + length(capture_start)
    matches <- character(total_matches)
    matches[1] <- substr(str, match, match + attr(match, 'match.length') - 1)
    if (length(capture_start) > 1) {
      for (i in 1:length(capture_start)) {
        matches[i + 1] <- substr(str, capture_start[[i]], capture_start[[i]] + capture_length[[i]] - 1)
      }
    }
  }
  matches
}

Voilà comment je fini par travailler autour de ce problème. J'ai utilisé deux regexes séparés pour correspondre aux premier et deuxième groupes de capture et exécuter deux appels gregexpr, puis retirez-les sous-chaînes assortis:

regex.string <- "(?<=\\().*?(?= :: )"
regex.number <- "(?<= :: )\\d\\.\\d+"

match.string <- gregexpr(regex.string, str, perl=T)[[1]]
match.number <- gregexpr(regex.number, str, perl=T)[[1]]

strings <- mapply(function (start, len) substr(str, start, start+len-1),
                  match.string,
                  attr(match.string, "match.length"))
numbers <- mapply(function (start, len) as.numeric(substr(str, start, start+len-1)),
                  match.number,
                  attr(match.number, "match.length"))

Solution avec strcapture du utils:

x <- c("key1 :: 0.01",
       "key2 :: 0.02")
strcapture(pattern = "(.*) :: (0\\.[0-9]+)",
           x = x,
           proto = list(key = character(), value = double()))
#>    key value
#> 1 key1  0.01
#> 2 key2  0.02

Comme suggéré dans le package stringr , cela peut être réalisé en utilisant soit str_match() ou str_extract().

Adapté du manuel:

library(stringr)

strings <- c(" 219 733 8965", "329-293-8753 ", "banana", 
             "239 923 8115 and 842 566 4692",
             "Work: 579-499-7527", "$1000",
             "Home: 543.355.3679")
phone <- "([2-9][0-9]{2})[- .]([0-9]{3})[- .]([0-9]{4})"

et en combinant nos extraction groupes:

str_extract_all(strings, phone, simplify=T)
#      [,1]           [,2]          
# [1,] "219 733 8965" ""            
# [2,] "329-293-8753" ""            
# [3,] ""             ""            
# [4,] "239 923 8115" "842 566 4692"
# [5,] "579-499-7527" ""            
# [6,] ""             ""            
# [7,] "543.355.3679" ""   

Indiquant des groupes avec une matrice de sortie (qui nous intéresse dans les colonnes 2 +):

str_match_all(strings, phone)
# [[1]]
#      [,1]           [,2]  [,3]  [,4]  
# [1,] "219 733 8965" "219" "733" "8965"
# 
# [[2]]
#      [,1]           [,2]  [,3]  [,4]  
# [1,] "329-293-8753" "329" "293" "8753"
# 
# [[3]]
#      [,1] [,2] [,3] [,4]
# 
# [[4]]
#      [,1]           [,2]  [,3]  [,4]  
# [1,] "239 923 8115" "239" "923" "8115"
# [2,] "842 566 4692" "842" "566" "4692"
# 
# [[5]]
#      [,1]           [,2]  [,3]  [,4]  
# [1,] "579-499-7527" "579" "499" "7527"
# 
# [[6]]
#      [,1] [,2] [,3] [,4]
# 
# [[7]]
#      [,1]           [,2]  [,3]  [,4]  
# [1,] "543.355.3679" "543" "355" "3679"
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top