Извлеките регулярное выражение
Я пытаюсь извлечь число из строки.
И сделайте что-нибудь вроде [0-9]+
на строке "aaa12xxx"
и получите "12"
.
Я думал, что это будет что-то вроде:
> grep("[0-9]+", "aaa12xxx", value=TRUE)
[1] "aaa12xxx"
И потом я подумал...
> sub("[0-9]+", "\\1", "aaa12xxx")
[1] "aaaxxx"
Но я получил некоторую форму ответа:
> sub("[0-9]+", "ARGH!", "aaa12xxx")
[1] "aaaARGH!xxx"
Там небольшая деталь, которую мне не хватает.
Ответы
Ответ 1
Используйте новый пакет stringr, который обертывает все существующее регулярное выражение, работает в согласованном синтаксисе и добавляет несколько отсутствующих:
library(stringr)
str_locate("aaa12xxx", "[0-9]+")
# start end
# [1,] 4 5
str_extract("aaa12xxx", "[0-9]+")
# [1] "12"
Ответ 2
Скорее поспешно сказать "игнорировать стандартные функции" - файл справки для ?gsub
, даже конкретно ссылки в "Смотрите также":
'для извлечения согласованных подстрок на основе результатов 'Regexpr,' gregexpr и 'regexec.
Итак, это сработает и довольно просто:
txt <- "aaa12xxx"
regmatches(txt,regexpr("[0-9]+",txt))
#[1] "12"
Ответ 3
Может
gsub("[^0-9]", "", "aaa12xxxx")
# [1] "12"
Ответ 4
Вы можете использовать ленивое совпадение регулярных выражений PERL:
> sub(".*?([0-9]+).*", "\\1", "aaa12xx99",perl=TRUE)
[1] "12"
Попытка заменить лишние цифры приведет к ошибке в этом случае.
Ответ 5
Используйте скобки для скобок в регулярном выражении и ссылках на группы в замене. Все, что в скобках запоминается. Затем к ним обращается \2, первый элемент. Первая обратная косая черта избегает интерпретации обратной косой черты в R, поэтому она передается в парсер регулярного выражения.
gsub('([[:alpha:]]+)([0-9]+)([[:alpha:]]+)', '\\2', "aaa12xxx")
Ответ 6
Один из способов:
test <- regexpr("[0-9]+","aaa12456xxx")
Теперь обратите внимание, что regexpr дает начальные и конечные индексы строки:
> test
[1] 4
attr(,"match.length")
[1] 5
Таким образом, вы можете использовать эту информацию с помощью функции substr
substr("aaa12456xxx",test,test+attr(test,"match.length")-1)
Я уверен, что есть более элегантный способ сделать это, но это был самый быстрый способ найти. Кроме того, вы можете использовать sub/gsub, чтобы вырезать то, что вы не хотите оставлять, что хотите.
Ответ 7
Использование обложки в пакете gsubfn. как правило, применяется в том, что args являются объектом, модификатором и функцией, за исключением того, что объект является вектором строк (а не массивом), а модификатор является регулярным выражением (а не разницей):
library(gsubfn)
x <- c("xy13", "ab 12 cd 34 xy")
strapply(x, "\\d+", as.numeric)
# list(13, c(12, 34))
Это говорит о том, чтобы соответствовать одной или нескольким цифрам (\ d +) в каждом компоненте x, проходящем каждый матч через as.numeric. Он возвращает список, компоненты которого являются векторами совпадений соответствующих компонентов x. Посмотрев на выходе, мы видим, что первая компонента x имеет одно совпадение, равное 13, а вторая компонента x имеет два совпадения, равные 12 и 34. См. http://gsubfn.googlecode.com для получения дополнительной информации.
Ответ 8
Другое решение:
temp = regexpr('\\d', "aaa12xxx");
substr("aaa12xxx", temp[1], temp[1]+attr(temp,"match.length")[1])
Ответ 9
Одним из важных различий между этими подходами является поведение с любыми несоответствиями. Например, метод regmatches может не возвращать строку с той же длиной, что и вход, если нет совпадений во всех позициях
> txt <- c("aaa12xxx","xyz")
> regmatches(txt,regexpr("[0-9]+",txt)) # could cause problems
[1] "12"
> gsub("[^0-9]", "", txt)
[1] "12" ""
> str_extract(txt, "[0-9]+")
[1] "12" NA
Ответ 10
Вы можете написать свои регулярные выражения с помощью С++, скомпилировать их в DLL и вызвать их из R.
#include <regex>
extern "C" {
__declspec(dllexport)
void regex_match( const char **first, char **regexStr, int *_bool)
{
std::cmatch _cmatch;
const char *last = *first + strlen(*first);
std::regex rx(*regexStr);
bool found = false;
found = std::regex_match(*first,last,_cmatch, rx);
*_bool = found;
}
__declspec(dllexport)
void regex_search_results( const char **str, const char **regexStr, int *N, char **out )
{
std::string s(*str);
std::regex rgx(*regexStr);
std::smatch m;
int i=0;
while(std::regex_search(s,m,rgx) && i < *N) {
strcpy(out[i],m[0].str().c_str());
i++;
s = m.suffix().str();
}
}
};
вызов в R как
dyn.load("C:\\YourPath\\RegTest.dll")
regex_match <- function(str,regstr) {
.C("regex_match",x=as.character(str),y=as.character(regstr),z=as.logical(1))$z }
regex_match("abc","a(b)c")
regex_search_results <- function(x,y,n) {
.C("regex_search_results",x=as.character(x),y=as.character(y),i=as.integer(n),z=character(n))$z }
regex_search_results("aaa12aa34xxx", "[0-9]+", 5)