Ecco un modo per estrarre tutte le corrispondenze sovrapposte di lunghezza variabile utilizzando gregexpr
.
x<-"abaaaababaaa"
# nest in lookahead + capture group
# to get all instances of the pattern "(ab)|b"
matches<-gregexpr('(?=((ab)|b))', x, perl=TRUE)
# regmatches will reference the match.length attr. to extract the strings
# so move match length data from 'capture.length' to 'match.length' attr
attr(matches[[1]], 'match.length') <- as.vector(attr(matches[[1]], 'capture.length')[,1])
# extract substrings
regmatches(x, matches)
# [[1]]
# [1] "ab" "b" "ab" "b" "ab" "b"
Il trucco è quello di circondare il modello in un gruppo di cattura e che catturare il gruppo in un'asserzione lookahead. gregexpr
restituirà una lista contenente le posizioni iniziali con un attributo capture.length
, una matrice in cui la prima colonna corrisponde alle lunghezze della corrispondenza del primo gruppo di cattura. Se lo converti in un vettore e lo sposti nell'attributo match.length
(che è tutti zeri, poiché l'intero pattern era all'interno di un'asserzione lookahead), puoi passarlo a regmatches
per estrarre le stringhe.
Come suggerito dal tipo di risultato finale, con alcune modifiche, questo può essere vettorizzato, nel caso in cui x
è un elenco di stringhe.
x<-list(s1="abaaaababaaa", s2="ab")
matches<-gregexpr('(?=((ab)|b))', x, perl=TRUE)
# make a function that replaces match.length attr with capture.length
set.match.length<-
function(x) structure(x, match.length=as.vector(attr(x, 'capture.length')[,1]))
# set match.length to capture.length for each match object
matches<-lapply(matches, set.match.length)
# extract substrings
mapply(regmatches, x, lapply(matches, list))
# $s1
# [1] "ab" "b" "ab" "b" "ab" "b"
#
# $s2
# [1] "ab" "b"
fonte
2013-01-22 06:11:27
Questo fa anche il lavoro (up-votato), ma voglio evitare cicli espliciti, le mie stringhe sono piuttosto lunghe. –
@AdityaSihag, potrebbe essere decisamente ottimizzato, volevo solo lanciare questa soluzione anche lì. –