У меня есть такая строка:
text <- "This is some text::stuff. Look, there's some::more. And here::is some more."
Я хотел бы извлечь слова перед двойным двоеточием. Для этого я использую gregexpr
для сопоставления буквенно-цифровых символов непосредственно перед двойным двоеточием:
m <- gregexpr("[[:alnum:]]*::", text)
Затем я вызываю regmatches
, чтобы извлечь этот текст, unlist
результат в вектор и, наконец, удалить двойные двоеточия с помощью gsub
.
gsub("::", "", unlist(regmatches(text, m)))
#[1] "text" "some" "here"
Это желаемый результат, но он зависит от четырех вызовов функций. Есть ли более эффективный способ достижения того же результата?
Ты можешь использовать
m <- gregexpr("[[:alnum:]]+(?=::)", text, perl=TRUE)
См. демонстрация регулярных выражений. Здесь [[:alnum:]]+(?=::)
сопоставляется одной или нескольким буквам или цифрам, а затем проверяет, следуют ли сразу за ними два двоеточия, не потребляя двоеточия, поскольку (?=...)
является не потребляющей опережающей конструкцией.
Имейте в виду, что аргумент perl=TRUE
становится здесь обязательным, поскольку механизм регулярных выражений TRE по умолчанию не позволяет использовать поиск. perl=TRUE
включает движок регулярных выражений PCRE, а также позволяет использовать как ретроспективный, так и прогнозный анализ.
См. демонстрация R:
text <- "This is some text::stuff. Look, there's some::more. And here::is some more."
m <- gregexpr("[[:alnum:]]+(?=::)", text, perl=TRUE)
unlist(regmatches(text, m))
## => [1] "text" "some" "here"
Вы можете использовать предпросмотр и str_extract_all
, чтобы сделать все это за один раз:
library(stringr)
str_extract_all(text, "\\w+(?=::)")[[1]]
[1] "text" "some" "here"
Вы также можете использовать группу захвата вместо поиска и повторить [[:alnum:]]+
1 или более раз, чтобы предотвратить сопоставление пустых строк.
library(stringr)
text <- "This is some text::stuff. Look, there's some::more. And here::is some more."
str_match_all(text, "([[:alnum:]]+)::")[[1]][,2]
Выход
[1] "text" "some" "here"
См. демонстрация R
И чтобы уточнить для других, интересующихся (как и я):
\w
относится к словесным символам (например, 0–9, az, AZ, _ и т. д.) и, как объясняет Виктор в другом ответе,(?=...)
является не потребляющей опережающей конструкцией. .