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

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ście

  • gsub(pattern,replacement,text) zrobi to samo co sub, ale dla każdego wystąpienia wzorca

  • regexpr(pattern,text) zwróci pozycję dopasowania dla pierwszego wystąpienia wzorca

  • gregexpr(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)
  }))
} 


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow