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)
}))
}