R Language
Patroonaanpassing en vervanging
Zoeken…
Invoering
Dit onderwerp behandelt bijpassende tekenreekspatronen, evenals het extraheren of vervangen ervan. Zie Reguliere expressies voor meer informatie over het definiëren van gecompliceerde patronen.
Syntaxis
grep ("query", "subject", optioneel_args)
grepl ("query", "subject", optioneel_args)
gsub ("(groep1) (groep2)", "\\ groep #", "onderwerp")
Opmerkingen
Verschillen met andere talen
Ontsnapte regex- symbolen (zoals \1
) moeten een tweede keer worden ontsnapt (zoals \\1
), niet alleen in het pattern
, maar ook in de replacement
van sub
en gsub
.
Standaard is het patroon voor alle opdrachten (grep, sub, regexpr) niet Perl-compatibele reguliere expressie (PCRE), dus sommige dingen zoals lookarounds worden niet ondersteund. Elke functie accepteert echter een perl=TRUE
argument om ze in te schakelen. Zie het onderwerp R Reguliere uitdrukkingen voor details.
Gespecialiseerde pakketten
- Stringi
- stringr
Vervangingen maken
# example data
test_sentences <- c("The quick brown fox quickly", "jumps over the lazy dog")
Laten we de bruine vos rood maken:
sub("brown","red", test_sentences)
#[1] "The quick red fox quickly" "jumps over the lazy dog"
Laten we nu de "fast"
vos "fastly"
handelen. Dit zal het niet doen:
sub("quick", "fast", test_sentences)
#[1] "The fast red fox quickly" "jumps over the lazy dog"
sub
maakt alleen de eerste beschikbare vervanging, we hebben gsub
nodig voor wereldwijde vervanging :
gsub("quick", "fast", test_sentences)
#[1] "The fast red fox fastly" "jumps over the lazy dog"
Zie Strings wijzigen door vervanging voor meer voorbeelden.
Overeenkomsten zoeken
# example data
test_sentences <- c("The quick brown fox", "jumps over the lazy dog")
Is er een match?
grepl()
wordt gebruikt om te controleren of een woord of reguliere expressie voorkomt in een tekenreeks of grepl()
. De functie retourneert een TRUE / FALSE (of "Boolean") vector.
Merk op dat we elke string kunnen controleren op het woord "fox" en in ruil daarvoor een Booleaanse vector ontvangen.
grepl("fox", test_sentences)
#[1] TRUE FALSE
Match locaties
grep
neemt een tekenreeks en een reguliere expressie in. Het retourneert een numerieke vector van indexen. Dit geeft terug welke zin het woord "vos" bevat.
grep("fox", test_sentences)
#[1] 1
Overeenkomende waarden
Zinnen selecteren die overeenkomen met een patroon:
# 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"
Details
Omdat het "fox"
-patroon slechts een woord is, in plaats van een reguliere uitdrukking, kunnen we de prestaties verbeteren (met grep
of grepl
) door fixed = TRUE
specificeren.
grep("fox", test_sentences, fixed = TRUE)
#[1] 1
Om zinnen te selecteren die niet overeenkomen met een patroon, kan men grep
met invert = TRUE
; of volg deelverzameling regels -grep(...)
of !grepl(...)
.
In zowel grepl(pattern, x)
als grep(pattern, x)
is de parameter x
gevectoriseerd , de parameter pattern
niet. Daarom kunt u deze niet rechtstreeks gebruiken om pattern[1]
met x[1]
, pattern[2]
tegen x[2]
, enzovoort.
Samenvatting van wedstrijden
Na het uitvoeren van bijvoorbeeld de opdracht grepl
, wilt u misschien een overzicht krijgen van het aantal overeenkomsten waar TRUE
of FALSE
. Dit is handig, bijvoorbeeld in het geval van grote gegevenssets. Voer hiervoor de summary
uit:
# example data
test_sentences <- c("The quick brown fox", "jumps over the lazy dog")
# find matches
matches <- grepl("fox", test_sentences)
# overview
summary(matches)
Single en Global match.
Bij het werken met reguliere expressies is één modifier voor PCRE g
voor globale overeenkomst.
In R hebben matching- en vervangingsfuncties twee versies: first match en global match:
sub(pattern,replacement,text)
vervangt het eerste optreden van patroon door vervanging in tekstgsub(pattern,replacement,text)
zal hetzelfde doen als sub maar voor elk voorkomen van patroonregexpr(pattern,text)
retourneert de positie van de overeenkomst voor de eerste instantie van het patroongregexpr(pattern,text)
retourneert alle overeenkomsten.
Enkele willekeurige gegevens:
set.seed(123)
teststring <- paste0(sample(letters,20),collapse="")
# teststring
#[1] "htjuwakqxzpgrsbncvyo"
Laten we eens kijken hoe dit werkt als we klinkers door iets anders willen vervangen:
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** "
Laten we nu eens kijken hoe we een medeklinker kunnen vinden onmiddellijk gevolgd door een of meer klinkers:
regexpr("[^aeiou][aeiou]+",teststring)
#[1] 3
#attr(,"match.length")
#[1] 2
#attr(,"useBytes")
#[1] TRUE
We hebben een match op positie 3 van de string van lengte 2, dat wil zeggen: ju
Als we nu alle wedstrijden willen krijgen:
gregexpr("[^aeiou][aeiou]+",teststring)
#[[1]]
#[1] 3 5 19
#attr(,"match.length")
#[1] 2 2 2
#attr(,"useBytes")
#[1] TRUE
Dit alles is echt geweldig, maar dit geeft alleen gebruik van regmatches
en dat is niet zo gemakkelijk om te krijgen wat is gekoppeld, en hier komt regmatches
het enige doel is om de overeenkomende string uit regexpr te extraheren, maar het heeft een andere syntaxis.
Laten we onze overeenkomsten opslaan in een variabele en ze vervolgens uit de oorspronkelijke reeks extraheren:
matches <- gregexpr("[^aeiou][aeiou]+",teststring)
regmatches(teststring,matches)
#[[1]]
#[1] "ju" "wa" "yo"
Dit klinkt misschien vreemd om geen snelkoppeling te hebben, maar dit laat extractie uit een andere string toe door de overeenkomsten van onze eerste (denk aan het vergelijken van twee lange vectoren waarvan je weet dat er een gemeenschappelijk patroon is voor de eerste maar niet voor de tweede, dit staat een eenvoudige vergelijking):
teststring2 <- "this is another string to match against"
regmatches(teststring2,matches)
#[[1]]
#[1] "is" " i" "ri"
Let op: het patroon is standaard geen Perl-compatibele reguliere expressie, sommige dingen zoals lookarounds worden niet ondersteund, maar elke hier gepresenteerde functie staat perl=TRUE
argument toe om ze in te schakelen.
Vind overeenkomsten in big data-sets
In het geval van big data-sets grepl("fox", test_sentences)
de aanroep van grepl("fox", test_sentences)
niet goed. Grote gegevenssets zijn bijvoorbeeld gecrawlde websites of miljoenen tweets, enz.
De eerste versnelling is het gebruik van de optie perl = TRUE
. Nog sneller is de optie fixed = TRUE
. Een volledig voorbeeld zou zijn:
# example data
test_sentences <- c("The quick brown fox", "jumps over the lazy dog")
grepl("fox", test_sentences, perl = TRUE)
#[1] TRUE FALSE
In het geval van tekst mining wordt vaak een corpus gebruikt. Een corpus kan niet rechtstreeks met grepl
worden gebruikt. Overweeg daarom deze functie:
searchCorpus <- function(corpus, pattern) {
return(tm_index(corpus, FUN = function(x) {
grepl(pattern, x, ignore.case = TRUE, perl = TRUE)
}))
}