R Language
Dopasowywanie i zastępowanie wzorów
Szukaj…
Wprowadzenie
Ten temat obejmuje dopasowanie wzorców ciągów, a także ich wyodrębnianie lub zastępowanie. Szczegółowe informacje na temat definiowania skomplikowanych wzorców znajdują się w Wyrażeniach regularnych .
Składnia
grep („zapytanie”, „temat”, opcjonalne argumenty)
grepl („zapytanie”, „temat”, opcjonalne argumenty)
gsub („(grupa 1) (grupa 2)”, „\\ grupa nr”, „temat”)
Uwagi
Różnice w stosunku do innych języków
Uciekły regex symbole (jak \1
) są musi być dodana po raz drugi (jak \\1
), a nie tylko w pattern
argumentu, a także w replacement
na sub
i gsub
.
Domyślnie wzorzec dla wszystkich poleceń (grep, sub, regexpr) nie jest zgodny z wyrażeniem regularnym zgodnym z Perl (PCRE), więc niektóre rzeczy, takie jak wygląd, nie są obsługiwane. Jednak każda funkcja akceptuje argument perl=TRUE
aby je włączyć. Aby uzyskać szczegółowe informacje, zobacz temat Wyrażenia regularne R.
Specjalistyczne pakiety
- stringi
- stringr
Dokonywanie zastępstw
# example data
test_sentences <- c("The quick brown fox quickly", "jumps over the lazy dog")
Zróbmy brązowego lisa czerwonym:
sub("brown","red", test_sentences)
#[1] "The quick red fox quickly" "jumps over the lazy dog"
Teraz sprawmy, by "fast"
lis działał "fastly"
. To nie zrobi tego:
sub("quick", "fast", test_sentences)
#[1] "The fast red fox quickly" "jumps over the lazy dog"
sub
tworzy tylko pierwszą dostępną wymianę, potrzebujemy gsub
do globalnej wymiany :
gsub("quick", "fast", test_sentences)
#[1] "The fast red fox fastly" "jumps over the lazy dog"
Zobacz Modyfikowanie ciągów przez podstawienie, aby uzyskać więcej przykładów.
Znajdowanie dopasowań
# example data
test_sentences <- c("The quick brown fox", "jumps over the lazy dog")
Czy istnieje dopasowanie?
grepl()
służy do sprawdzania, czy słowo lub wyrażenie regularne istnieje w wektorze ciągów lub znaków. Funkcja zwraca wektor PRAWDA / FAŁSZ (lub „wartość logiczna”).
Zauważ, że możemy sprawdzić każdy łańcuch pod kątem słowa „lis” i otrzymać w zamian wektor boolowski.
grepl("fox", test_sentences)
#[1] TRUE FALSE
Dopasuj lokalizacje
grep
przyjmuje ciąg znaków i wyrażenie regularne. Zwraca wektor numeryczny indeksów, który zwróci w którym zdaniu zawiera słowo „lis”.
grep("fox", test_sentences)
#[1] 1
Dopasowane wartości
Aby wybrać zdania pasujące do wzoru:
# 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"
Detale
Ponieważ wzorzec "fox"
jest tylko słowem, a nie wyrażeniem regularnym, moglibyśmy poprawić wydajność (za pomocą grep
lub grepl
) poprzez określenie fixed = TRUE
.
grep("fox", test_sentences, fixed = TRUE)
#[1] 1
Aby wybrać zdania, które nie pasują do wzorca, można użyć grep
z invert = TRUE
; lub śledzić podzbiorów reguł z -grep(...)
lub !grepl(...)
.
Zarówno w grepl(pattern, x)
i grep(pattern, x)
parametr x
jest wektoryzowany , a parametr pattern
nie. W rezultacie nie można ich użyć bezpośrednio do dopasowania pattern[1]
do x[1]
, pattern[2]
do x[2]
i tak dalej.
Podsumowanie dopasowań
Po wykonaniu np. Polecenia grepl
może chcesz uzyskać przegląd liczby dopasowań, w których TRUE
lub FALSE
. Jest to przydatne np. W przypadku dużych zbiorów danych. W tym celu uruchom polecenie 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)
Mecz pojedynczy i globalny.
Podczas pracy z wyrażeniami regularnymi jednym modyfikatorem PCRE jest g
dla dopasowania globalnego.
W R funkcje dopasowania i zamiany mają dwie wersje: pierwsze dopasowanie i dopasowanie globalne:
sub(pattern,replacement,text)
zastąpi pierwsze wystąpienie wzorca zastąpieniem w tekściegsub(pattern,replacement,text)
zrobi to samo co sub, ale dla każdego wystąpienia wzorcaregexpr(pattern,text)
zwróci pozycję dopasowania dla pierwszego wystąpienia wzorcagregexpr(pattern,text)
zwróci wszystkie dopasowania.
Niektóre losowe dane:
set.seed(123)
teststring <- paste0(sample(letters,20),collapse="")
# teststring
#[1] "htjuwakqxzpgrsbncvyo"
Zobaczmy, jak to działa, jeśli chcemy zastąpić samogłoski czymś innym:
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** "
Zobaczmy teraz, jak możemy znaleźć spółgłoskę, po której następuje jedna lub więcej samogłosek:
regexpr("[^aeiou][aeiou]+",teststring)
#[1] 3
#attr(,"match.length")
#[1] 2
#attr(,"useBytes")
#[1] TRUE
Mamy dopasowanie do pozycji 3 ciągu o długości 2, tj .: ju
Teraz jeśli chcemy uzyskać wszystkie mecze:
gregexpr("[^aeiou][aeiou]+",teststring)
#[[1]]
#[1] 3 5 19
#attr(,"match.length")
#[1] 2 2 2
#attr(,"useBytes")
#[1] TRUE
Wszystko to jest naprawdę świetne, ale daje to tylko pozycje dopasowania i nie jest tak łatwo uzyskać to, co jest dopasowane, a tutaj nadchodzą regmatches
, jedynym celem jest wyodrębnienie dopasowanego łańcucha z regexpr, ale ma inną składnię.
Zapiszmy nasze dopasowania w zmiennej, a następnie wyodrębnij je z oryginalnego ciągu:
matches <- gregexpr("[^aeiou][aeiou]+",teststring)
regmatches(teststring,matches)
#[[1]]
#[1] "ju" "wa" "yo"
To może zabrzmieć dziwnie, jeśli nie ma skrótu, ale pozwala to na wyodrębnienie z innego ciągu dopasowaniami naszego pierwszego (pomyśl, porównując dwa długie wektory, w których wiesz, że istnieje wspólny wzór dla pierwszego, ale nie dla drugiego, to pozwala łatwe porównanie):
teststring2 <- "this is another string to match against"
regmatches(teststring2,matches)
#[[1]]
#[1] "is" " i" "ri"
Uwaga: domyślnie wzorzec nie jest zgodny z wyrażeniem regularnym zgodnym z Perl, niektóre rzeczy, takie jak lookarounds, nie są obsługiwane, ale każda przedstawiona tutaj funkcja pozwala na włączenie argumentu perl=TRUE
.
Znajdź dopasowania w dużych zbiorach danych
W przypadku dużych zbiorów danych wywołanie grepl("fox", test_sentences)
nie działa dobrze. Zestawy dużych danych to np. Zaindeksowane witryny lub milion tweetów itp.
Pierwszym przyspieszeniem jest użycie opcji perl = TRUE
. Jeszcze szybsza jest opcja fixed = TRUE
. Kompletnym przykładem byłoby:
# example data
test_sentences <- c("The quick brown fox", "jumps over the lazy dog")
grepl("fox", test_sentences, perl = TRUE)
#[1] TRUE FALSE
W przypadku eksploracji tekstu często wykorzystywany jest korpus. grepl
nie można używać bezpośrednio z grepl
. Dlatego rozważ tę funkcję:
searchCorpus <- function(corpus, pattern) {
return(tm_index(corpus, FUN = function(x) {
grepl(pattern, x, ignore.case = TRUE, perl = TRUE)
}))
}