Ответ 1
Пребывание с regexpr
:
r <- regexpr("a+", x)
out <- rep(NA,length(x))
out[r!=-1] <- regmatches(x, r)
out
#[1] "a" NA "a" "aa"
Я хотел бы зафиксировать первое совпадение и вернуть NA
, если совпадения нет.
regexpr("a+", c("abc", "def", "cba a", "aa"), perl=TRUE)
# [1] 1 -1 3 1
# attr(,"match.length")
# [1] 1 -1 1 2
x <- c("abc", "def", "cba a", "aa")
m <- regexpr("a+", x, perl=TRUE)
regmatches(x, m)
# [1] "a" "a" "aa"
Поэтому я ожидал "a", NA, "a", "aa"
Пребывание с regexpr
:
r <- regexpr("a+", x)
out <- rep(NA,length(x))
out[r!=-1] <- regmatches(x, r)
out
#[1] "a" NA "a" "aa"
используйте regexec
вместо этого, поскольку он возвращает список, который позволит вам поймать character(0)
до unlist
ing
R <- regmatches(x, regexec("a+", x))
unlist({R[sapply(R, length)==0] <- NA; R})
# [1] "a" NA "a" "aa"
В R 3.3.0 можно извлечь как совпадения, так и несоответствующие результаты, используя аргумент invert = NA. Из справочного файла написано
если инвертирование равно NA, regmatches извлекает как несоответствующие, так и совпадающие подстроки, всегда начинающиеся и заканчивающиеся несоответствием (пусто, если совпадение произошло в начале или в конце соответственно).
Вывод представляет собой список, как правило, в большинстве случаев представляющий интерес (соответствующий одному шаблону), regmatches
с этим аргументом возвращают список с элементами длиной 3 или 1. 1 - случай, когда совпадений не найдено, и 3 это случай со спичкой.
myMatch <- regmatches(x, m, invert=NA)
myMatch
[[1]]
[1] "" "a" "bc"
[[2]]
[1] "def"
[[3]]
[1] "cb" "a" " a"
[[4]]
[1] "" "aa" ""
Таким образом, чтобы извлечь то, что вы хотите (с "" вместо NA), вы можете использовать sapply
следующим образом:
myVec <- sapply(myMatch, function(x) {if(length(x) == 1) "" else x[2]})
myVec
[1] "a" "" "a" "aa"
На этом этапе, если вы действительно хотите NA вместо "", вы можете использовать
is.na(myVec) <- nchar(myVec) == 0L
myVec
[1] "a" NA "a" "aa"
Некоторые изменения:
Обратите внимание, что вы можете свернуть последние две строки в одну строку:
myVec <- sapply(myMatch, function(x) {if(length(x) == 1) NA_character_ else x[2]})
Тип данных по умолчанию NA
является логическим, поэтому его использование приведет к дополнительным преобразованиям данных. Использование версии NA_character_
позволяет избежать этого.
Еще один способ извлечения для последней строки - использовать [
:
sapply(myMatch, '[', 2)
[1] "a" NA "a" "aa"
Таким образом, вы можете сделать все это в одной удобочитаемой строке:
sapply(regmatches(x, m, invert=NA), '[', 2)
Используя более или менее ту же конструкцию, что и ваша -
chars <- c("abc", "def", "cba a", "aa")
chars[
regexpr("a+", chars, perl=TRUE) > 0
][1] #abc
chars[
regexpr("q", chars, perl=TRUE) > 0
][1] #NA
#vector[
# find all indices where regexpr returned positive value i.e., match was found
#][return the first element of the above subset]
Изменить - Кажется, я неправильно понял вопрос. Но так как два человека нашли это полезным, я оставлю его.