Более короткий способ извлечь последний набор цифр, начиная с конца

Я хотел бы извлечь последний набор цифр из строки, не делая этого.

"sdkjfn45sdjk54()ad"

str_remove("sdkjfn45sdjk54()ad","[:alpha:]+$")
[1] "sdkjfn45sdjk54()"

str_remove(str_remove("sdkjfn45sdjk54()ad","[:alpha:]+$"), "\\(")
[1] "sdkjfn45sdjk54)"

str_remove(str_remove(str_remove("sdkjfn45sdjk54()ad","[:alpha:]+$"), "\\("), "\\)")
[1] "sdkjfn45sdjk54"

str_extract(str_remove(str_remove(str_remove("sdkjfn45sdjk54()ad","[:alpha:]+$"), "\\("), "\\)"), "\\d+$")
[1] "54"

потому что схемы неопределенные. Я знаю, что у stringi есть функция str_extract_from_last, но мне нужно придерживаться base R или stringR.

Спасибо!


person Jantje Houten    schedule 20.04.2021    source источник
comment
Попробуйте: sub("^.*?(\\d+).*$", "\\1", "sdkjfn45sdjk54()ad")   -  person GKi    schedule 20.04.2021


Ответы (2)


Вы можете использовать отрицательное регулярное выражение.

string <- "sdkjfn45sdjk54()ad"
stringr::str_extract(string, '(\\d+)(?!.*\\d)')
#[1] "54"

Использование того же регулярного выражения в базе R:

regmatches(string, gregexpr('(\\d+)(?!.*\\d)', string, perl = TRUE))[[1]]

Это извлекает набор чисел, за которым не следует ни одно число, поэтому последний набор чисел.

person Ronak Shah    schedule 20.04.2021
comment
Спасибо Ронак! Не могли бы вы рассказать мне о регулярном выражении для этого - '(\\d+)(?!.*\\d)'? - person Jantje Houten; 20.04.2021
comment
(\\d+) — одна или несколько цифр. (?!.*\\d) — это немного больше: (?! — это отрицательный прогноз, то есть он проверяется и сопоставляется, но не захватывается шаблоном. (Я думаю, что может понадобиться $, как в (?!.*\\d)$, но, возможно, нет.) Хороший справочник по регулярному выражению: stackoverflow.com/ a/22944075/3358272, признайте, что это общее регулярное выражение, и R требует двойной обратной косой черты везде, где в этом руководстве используется одинарная обратная косая черта. - person r2evans; 20.04.2021

Используйте str_extract_all и возьмите только последний в каждом векторе.

library(stringr)
quux <- str_extract_all(c("a", "sdkjfn45sdjk54()ad"), "[0-9]+")
sapply(quux, `[`, lengths(quux))
# [1] NA   "54"

Я использую sapply, потому что предполагаю, что у вас более одной строки. str_extract_all вернет list, где каждый элемент представляет собой ноль или более строк, извлеченных из источника. Поскольку нас интересует только один из них, мы можем использовать sapply.

Может возникнуть соблазн использовать sapply(., tail, 1), но если будет найден ноль, то это будет character(0), а не пустое или NA. Я предполагаю, что NA будет хорошим возвратом, если шаблон не найден.

person r2evans    schedule 20.04.2021