R Language
Согласование и замена шаблонов
Поиск…
Вступление
В этом разделе описываются соответствующие шаблоны строк, а также их извлечение или замена. Подробные сведения об определении сложных шаблонов см. В разделе Регулярные выражения .
Синтаксис
grep ("query", "subject", optional_args)
grepl ("query", "subject", optional_args)
gsub ("(group1) (group2)", "\\ group #", "subject")
замечания
Различия с другими языками
Экранированные символы регулярных выражений (например, \1
) должны быть экранированы во второй раз (например, \\1
) не только в аргументе pattern
, но и в replacement
sub
и gsub
.
По умолчанию шаблон для всех команд (grep, sub, regexpr) не является Perl Compatible Regular Expression (PCRE), поэтому некоторые вещи, такие как lookarounds, не поддерживаются. Однако каждая функция принимает аргумент perl=TRUE
для их включения. Дополнительную информацию см. В разделе « Регулярные выражения R» .
Специализированные пакеты
- стринги
- stringr
Выполнение замен
# example data
test_sentences <- c("The quick brown fox quickly", "jumps over the lazy dog")
Давайте сделаем коричневую лисицу красной:
sub("brown","red", test_sentences)
#[1] "The quick red fox quickly" "jumps over the lazy dog"
Теперь давайте сделаем "fast"
лисицу "fastly"
. Это не будет сделано:
sub("quick", "fast", test_sentences)
#[1] "The fast red fox quickly" "jumps over the lazy dog"
sub
делает только первую доступную замену, нам нужен gsub
для глобальной замены :
gsub("quick", "fast", test_sentences)
#[1] "The fast red fox fastly" "jumps over the lazy dog"
См. « Изменение строк» путем замены для большего количества примеров.
Поиск матчей
# example data
test_sentences <- c("The quick brown fox", "jumps over the lazy dog")
Есть ли матч?
grepl()
используется для проверки наличия слова или регулярного выражения в строке или символьном векторе. Функция возвращает вектор TRUE / FALSE (или «Boolean»).
Обратите внимание, что мы можем проверить каждую строку для слова «лиса» и получить взамен булевой вектор.
grepl("fox", test_sentences)
#[1] TRUE FALSE
Место встречи
grep
принимает строку символов и регулярное выражение. Он возвращает числовой вектор индексов. Это вернет, какое предложение содержит в нем слово «лиса».
grep("fox", test_sentences)
#[1] 1
Соответствующие значения
Чтобы выбрать предложения, соответствующие шаблону:
# each of the following lines does the job:
test_sentences[grep("fox", test_sentences)]
test_sentences[grepl("fox", test_sentences)]
grep("fox", test_sentences, value = TRUE)
# [1] "The quick brown fox"
подробности
Поскольку шаблон "fox"
- это просто слово, а не регулярное выражение, мы могли бы повысить производительность (с помощью grep
или grepl
), указав fixed = TRUE
.
grep("fox", test_sentences, fixed = TRUE)
#[1] 1
Чтобы выбрать предложения, не соответствующие шаблону, можно использовать grep
с invert = TRUE
; или следуйте правилам подмножества с помощью -grep(...)
или !grepl(...)
.
В обоих grepl(pattern, x)
и grep(pattern, x)
параметр x
векторизован , параметр pattern
- нет. В результате вы не можете использовать их напрямую, чтобы сопоставить pattern[1]
с x[1]
, pattern[2]
против x[2]
и т. Д.
Резюме матчей
После выполнения команды grepl
, возможно, вы хотите получить обзор о том, сколько совпадений имеют TRUE
или FALSE
. Это полезно, например, в случае больших наборов данных. Для этого выполните команду summary
:
# example data
test_sentences <- c("The quick brown fox", "jumps over the lazy dog")
# find matches
matches <- grepl("fox", test_sentences)
# overview
summary(matches)
Единый и глобальный матч.
При работе с регулярными выражениями один модификатор для PCRE равен g
для глобального соответствия.
В функциях соответствия и замены R есть две версии: первое совпадение и глобальное соответствие:
sub(pattern,replacement,text)
заменит первое вхождение шаблона заменой в текстеgsub(pattern,replacement,text)
будет делать то же самое, что и sub, но для каждого появления шаблонаregexpr(pattern,text)
вернет позицию соответствия для первого экземпляра шаблонаgregexpr(pattern,text)
вернет все совпадения.
Некоторые случайные данные:
set.seed(123)
teststring <- paste0(sample(letters,20),collapse="")
# teststring
#[1] "htjuwakqxzpgrsbncvyo"
Давайте посмотрим, как это работает, если мы хотим заменить гласные чем-то другим:
sub("[aeiouy]"," ** HERE WAS A VOWEL** ",teststring)
#[1] "htj ** HERE WAS A VOWEL** wakqxzpgrsbncvyo"
gsub("[aeiouy]"," ** HERE WAS A VOWEL** ",teststring)
#[1] "htj ** HERE WAS A VOWEL** w ** HERE WAS A VOWEL** kqxzpgrsbncv ** HERE WAS A VOWEL** ** HERE WAS A VOWEL** "
Теперь давайте посмотрим, как мы можем найти согласный, за которым следует один или несколько гласных:
regexpr("[^aeiou][aeiou]+",teststring)
#[1] 3
#attr(,"match.length")
#[1] 2
#attr(,"useBytes")
#[1] TRUE
Мы имеем совпадение на позиции 3 строки длины 2, т. ju
Теперь, если мы хотим получить все совпадения:
gregexpr("[^aeiou][aeiou]+",teststring)
#[[1]]
#[1] 3 5 19
#attr(,"match.length")
#[1] 2 2 2
#attr(,"useBytes")
#[1] TRUE
Все это действительно здорово, но это только дает использование позиции соответствия, и это не так просто получить то, что соответствует, и здесь идут regmatches
, единственная цель - извлечь строку, сопоставленную с regexpr, но она имеет другой синтаксис.
Давайте сохраним наши совпадения в переменной, а затем извлечем их из исходной строки:
matches <- gregexpr("[^aeiou][aeiou]+",teststring)
regmatches(teststring,matches)
#[[1]]
#[1] "ju" "wa" "yo"
Это может показаться странным, если у вас нет ярлыка, но это позволяет извлечь из другой строки совпадения нашей первой (подумайте о сравнении двух длинных векторов, где вы знаете, что существует общий шаблон для первого, но не для второго, это позволяет простое сравнение):
teststring2 <- "this is another string to match against"
regmatches(teststring2,matches)
#[[1]]
#[1] "is" " i" "ri"
Внимание: по умолчанию шаблон не является Perl Compatible Regular Expression, некоторые вещи, такие как lookarounds, не поддерживаются, но каждая представленная здесь функция допускает аргумент perl=TRUE
для их включения.
Найти совпадения в больших наборах данных
В случае больших наборов данных вызов grepl("fox", test_sentences)
работает не очень хорошо. Большие наборы данных, например, обходные сайты или миллионы твитов и т. Д.
Первым ускорением является использование параметра perl = TRUE
. Еще быстрее опция fixed = TRUE
. Полный пример:
# example data
test_sentences <- c("The quick brown fox", "jumps over the lazy dog")
grepl("fox", test_sentences, perl = TRUE)
#[1] TRUE FALSE
В случае текстовой обработки часто используется корпус. Корпус нельзя использовать напрямую с grepl
. Поэтому рассмотрим эту функцию:
searchCorpus <- function(corpus, pattern) {
return(tm_index(corpus, FUN = function(x) {
grepl(pattern, x, ignore.case = TRUE, perl = TRUE)
}))
}