Encontre a localização de um caractere na string

87

Eu gostaria de encontrar a localização de um caractere em uma string.

Dizer: string = "the2quickbrownfoxeswere2tired"

Eu gostaria que a função retornasse 4e 24- a localização do caractere do 2s em string.

ricardo
fonte
Por que usar um regex? R não tem um .indexOf()ou algo assim?
fge
1
Eu duvido. Os desenvolvedores eram Nixers e presumiram que todos conheciam regex. O manuseio da string de R é meio confuso.
IRTFM

Respostas:

115

Você pode usar gregexpr

 gregexpr(pattern ='2',"the2quickbrownfoxeswere2tired")


[[1]]
[1]  4 24
attr(,"match.length")
[1] 1 1
attr(,"useBytes")
[1] TRUE

ou talvez str_locate_alldo pacote stringrque é um wrapper para (a partir da versão 1.0)gregexpr stringi::stri_locate_allstringr

library(stringr)
str_locate_all(pattern ='2', "the2quickbrownfoxeswere2tired")

[[1]]
     start end
[1,]     4   4
[2,]    24  24

observe que você pode simplesmente usar stringi

library(stringi)
stri_locate_all(pattern = '2', "the2quickbrownfoxeswere2tired", fixed = TRUE)

Outra opção na base Rseria algo como

lapply(strsplit(x, ''), function(x) which(x == '2'))

deve funcionar (dado um vetor de caracteres x)

mnel
fonte
como podemos extrair os inteiros das listas / objetos retornados por suas três primeiras soluções?
3pitt de
Use em regexprvez de gregexprpara obter os inteiros facilmente. Ou use unlistna saída conforme indicado em outra resposta abaixo.
Arani,
41

Aqui está outra alternativa direta.

> which(strsplit(string, "")[[1]]=="2")
[1]  4 24
Jilber Urbina
fonte
Você pode explicar o que [[1]]faz?
francoiskroll
@francoiskroll, [[1]] representa o primeiro elemento da lista.
Prafulla de
20

Você pode fazer a saída apenas 4 e 24 usando não listar:

unlist(gregexpr(pattern ='2',"the2quickbrownfoxeswere2tired"))
[1]  4 24

fonte
2

encontre a posição da enésima ocorrência de str2 em str1 (mesma ordem de parâmetros do Oracle SQL INSTR), retorna 0 se não for encontrado

instr <- function(str1,str2,startpos=1,n=1){
    aa=unlist(strsplit(substring(str1,startpos),str2))
    if(length(aa) < n+1 ) return(0);
    return(sum(nchar(aa[1:n])) + startpos+(n-1)*nchar(str2) )
}


instr('xxabcdefabdddfabx','ab')
[1] 3
instr('xxabcdefabdddfabx','ab',1,3)
[1] 15
instr('xxabcdefabdddfabx','xx',2,1)
[1] 0
Abdelmonem Mahmoud Amer
fonte
2

Para encontrar apenas os primeiros locais, use lapply()com min():

my_string <- c("test1", "test1test1", "test1test1test1")

unlist(lapply(gregexpr(pattern = '1', my_string), min))
#> [1] 5 5 5

# or the readable tidyverse form
my_string %>%
  gregexpr(pattern = '1') %>%
  lapply(min) %>%
  unlist()
#> [1] 5 5 5

Para encontrar apenas os últimos locais, use lapply()com max():

unlist(lapply(gregexpr(pattern = '1', my_string), max))
#> [1]  5 10 15

# or the readable tidyverse form
my_string %>%
  gregexpr(pattern = '1') %>%
  lapply(max) %>%
  unlist()
#> [1]  5 10 15
MS Berends
fonte
1

Você também pode usar grep:

grep('2', strsplit(string, '')[[1]])
#4 24
AlexB
fonte