Strängar och regular expressions (regex)
Strängar är information som består av siffror, symboler och/eller bokstäver. En sträng kan således vara en blandning av dessa komponenter. I R definieras en sträng med hjälp av citattecken. Nedan definieras en sträng som sparas i objektet my_string
:
# Spara en sträng i ett objekt
my_string <- "Detta är en sträng!"
# Skriv ut objektet
my_string
[1] "Detta är en sträng!"
Innan vi går vidare ska vi aktivera paketet tidyverse
, som inkluderar paketet stringr
, vilket innehåller alla funktioner som behövs för att hantera strängar.
library(tidyverse)
── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
ggplot2 3.3.6 purrr 0.3.4
tibble 3.1.8 dplyr 1.0.10
tidyr 1.2.0 stringr 1.4.1
readr 2.1.2 forcats 0.5.1
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
dplyr::filter() masks stats::filter()
dplyr::lag() masks stats::lag()
Flera strängar kan definieras med funktionen c()
, vilken kombinerar flera element till en vektor:
my_string <- c("Detta är en sträng!", "Detta är en annan sträng")
my_string
[1] "Detta är en sträng!" "Detta är en annan sträng"
Strängarna ovan skapades med dubbla citattecken (" "
). Strängar kan bestå av ett enda tecken, eller innehålla kompletta böcker. Här nedan definieras tre strängar: en kort sträng (my_string_short
), en sträng som enbart består av siffror (my_string_numbers
) och en lång sträng (my_string_long
):
# En kort sträng
my_string_short <- c("Detta är en sträng!")
# En sträng enbart med siffror
my_string_numbers <- c("123")
# En lång sträng
my_string_long <- c("Salvador Domingo Felipe Jacinto Dalí i Domènech, 1:e markis av Púbol, född 11 maj 1904 i Figueres, Katalonien, Spanien, död 23 januari 1989 i Figueres, var en katalansk (spansk) surrealistisk konstnär. Dalí är mest känd för sina bisarra, absurda och drömska målningar, influerade av bland annat Freuds psykoanalys, Einsteins relativitetsteorier och renässansmåleri.[2][3] Ett av hans mest kända verk, Minnets envishet, blev klart 1931. Utöver måleri omfattade Dalís praktik även film, skulptur, fotografi och text. Han samarbetade med Walt Disney kring den Oscars-nominerade tecknade kortfilmen Destino, som släpptes postumt 2003. Han samarbetade också med Alfred Hitchcock i arbetet med filmen Trollbunden.")
Strängar och citattecken
Använd dubbla citattecken (""
) när du definierar en sträng. Använd bara enkla citattecken (''
) för att definiera en sträng som innehåller dubbla citattecken.
En sträng kan även skapas med enkla citattecken (' '
):
my_string <- c('Detta är en sträng!')
my_string
[1] "Detta är en sträng!"
Det rekommenderas dock att strängar definieras med dubbla citattecken.
Låt oss försöka definiera en sträng som innehåller citattecken:
my_string <- c("Han fick smeknamnet "Yoggi" men det gillade han inte")
my_string
Error: unexpected symbol in "my_string <- c("Han fick smeknamnet "Yoggi"
Det uppstår Error (fel) eftersom R inte vet hur citattecknen på Yoggi ("Yoggi"
) skall tolkas. Detta beror på att citattecken har en speciell betydelse i strängar, nämligen att klargöra strängens start och slut. R tror att strängen är slut vid första citattecknet innan bokstaven Y ("
Y..), men eftersom det citattecknet följs av ytterligare bokstäver så uppstår Error. Vi behöver följaktligen en metod för att berätta för R att citattecken i strängen faktiskt är en del av strängen, istället för ett tecken med en speciell funktion! Det finns fler tecken (.
, *
, ]
, etc) som kan orsaka sådan tvetydighet så att Error uppstår.
För att undvika denna tvetydighet används omvänt snedstreck (\
, backslash). Backslash berättar R att citattecknen på “Yoggi” ska betraktas som en del av strängen. Det innebär att backslash (\
) används för att undkomma (eng. escape) citattecknets speciella funktion. Låt oss försöka läsa in strängen en gång till men denna gången med \
innan varje citattecken i strängen:
my_string <- c("Han fick smeknamnet \"Ylle\" men det gillade han inte")
Det fungerade utan Error! Låt oss skriva ut strängen:
my_string
[1] "Han fick smeknamnet \"Ylle\" men det gillade han inte"
Notera att backslash (\
) är markerat när strängen skrivs ut. Anledningen till detta är att R indikerar var escape använts. Om du vill skriva ut (eng. print) en sträng utan escape (\
) använder du funktionen writeLines()
:
writeLines(my_string)
Han fick smeknamnet "Ylle" men det gillade han inte
På samma sätt måste enkla citattecken föregås av \
för att undvika tvetydighet:
my_string <- c('Han fick smeknamnet \'Ylle\' men det gillade han inte')
writeLines(my_string)
Han fick smeknamnet 'Ylle' men det gillade han inte
Just för citattecken kan man även undvika tvetydighet genom att använda dubbla citattecken för att definiera strängen och enkla citattecken inuti strängen, eller vice versa. Ett exempel följer:
my_string1 <- c("Han fick smeknamnet 'Svurre' men det gillade han inte")
writeLines(my_string)
Han fick smeknamnet 'Svurre' men det gillade han inte
my_string2 <- c('Han fick smeknamnet "Svurre" men det gillade han inte')
writeLines(my_string)
Han fick smeknamnet 'Svurre' men det gillade han inte
Nedanstående tabell visar andra speciella tecken och formateringar där escape behövs för undvika tvetydighet:
Escape character | Betydelse |
---|---|
\n | newline |
\r | carriage return |
\t | tab |
\b | backspace |
\a | alert (bell) |
\f | form feed |
\v | vertical tab |
\\ | backslash \ |
\’ | ASCII apostrophe ’ |
\” | ASCII quotation mark ” |
\` | ASCII grave accent (backtick) ` |
\nnn | character with given octal code (1, 2 or 3 digits) |
\xnn | character with given hex code (1 or 2 hex digits) |
\unnnn | Unicode character with given code (1--4 hex digits) |
\Unnnnnnnn | Unicode character with given code (1--8 hex digits) |
8.1 Stringr och regular expressions (regex)
Paketet stringr
innehåller alla nödvändiga funktioner för att hantera strängar i R. Nedan diskuteras de viktigaste funktionerna och därefter hur regular expressions kan användas för att skapa kraftfulla matchningar i strängar. De flesta funktioner i stringr
har prefix str_
. Låt oss börja med att definiera en sträng:
my_string <- c("Det är roligt att lära sig R!")
8.1.1 Identiska strängar
Vi skapar nu två vektorer som består av en identisk sträng (“Sommarlov”) och använder funktionen identical()
för att avgöra om de är identiska:
word_1 <- "Sommarlov"
word_2 <- "Sommarlov"
identical(word_1, word_2)
[1] TRUE
Som många andra R funktioner kan du använda utropstecken (!
) framför funktionens namn för att få omvänd effekt. Om funktionen identical()
klargör om två strängar är identiska, så klargör identical()
om strängarna inte är identiska. Vi undersöker nu om orden inte är identiska:
!identical(word_1, word_2)
[1] FALSE
8.1.2 Ändra skriftläge
Med funktionerna str_to_lower()
, str_to_sentence()
, str_to_title()
och str_to_upper()
i paketet stringr
kan du ändra en strängs skriftläge enligt följande:
# Konverterar bokstäver till gemener
str_to_lower(my_string)
[1] "det är roligt att lära sig r!"
# Konverterar strängen till mening
str_to_sentence(my_string)
[1] "Det är roligt att lära sig r!"
# Konverterar strängen till titelform
str_to_title(my_string)
[1] "Det Är Roligt Att Lära Sig R!"
# Konverterar bokstäver till versaler
str_to_upper(my_string)
[1] "DET ÄR ROLIGT ATT LÄRA SIG R!"
8.1.3 Längden på en sträng
Längden (antal tecken) på en sträng kan beräknas med str_length()
:
str_length(my_string)
[1] 29
Som alla andra funktioner i stringr
är str_length()
vektoriserad vilket innebär att om du tillämpar den på en vektor görs beräkningen på varje element i vektorn:
str_length(c("Hej", "Ja", "Kanske"))
[1] 3 2 6
8.1.4 Lokalisationer i strängar
Vi kan identifiera var längs strängen ett visst tecken är lokaliserat. Detta görs med funktionen str_locate()
. Följande exempel beräknar i vilken position bokstaven “t” finns, om den förekommer:
my_string <- c("Det är roligt att lära sig R!")
str_locate(my_string, 't')
start end
[1,] 3 3
Enligt resultatet matchades “t” mellan position 3 och 3, vilket innebär att bokstaven är det tredje tecknet i strängen. Notera dock att det finns flera “t” i strängen och för att identifiera samtliga dessa måste vi använda funktionen str_locate_all()
:
str_locate_all(my_string, 't')
[[1]]
start end
[1,] 3 3
[2,] 13 13
[3,] 16 16
[4,] 17 17
Vi ser att det finns totalt 4 stycken “t” och de förekommer som tecken 3, 13, 16 och 17.
8.1.5 Sortera strängar
För att sortera en character-vektor används funktionen str_sort()
:
my_names <- c('Benny', 'Adam', 'Caesar')
str_sort(my_names)
[1] "Adam" "Benny" "Caesar"
Nu skapar vi en data frame med förnamn och efternamn. Hädanefter kommer vi använda funktioner från paketet dplyr
för att skapa och modifiera kolumner.
# Skapar förnamn
first_name <- c('Maria', 'Mohammed', 'Magnus')
# Skapar efternamn
last_name <- c('Svensson', 'Ayman', 'Bentzel')
# Kombinerar till en tibble (data frame)
my_data <- tibble(first_name, last_name)
# Skriver ut vår data frame
my_data
# A tibble: 3 × 2
first_name last_name
<chr> <chr>
1 Maria Svensson
2 Mohammed Ayman
3 Magnus Bentzel
8.1.6 Kombinera strängar
Vi slår ihop förnamn och efternamn till en sträng med funktionen str_c()
. Funktionen har argumentet sep
som specificerar vilket tecken som skall separera strängarna. Vi väljer att separera strängarna med ett mellanrum.
Exempel med base R (inte dplyr
):
my_data$full_name <- str_c(my_data$first_name,
my_data$last_name,
sep = " ")
my_data
# A tibble: 3 × 3
first_name last_name full_name
<chr> <chr> <chr>
1 Maria Svensson Maria Svensson
2 Mohammed Ayman Mohammed Ayman
3 Magnus Bentzel Magnus Bentzel
Exempel med dplyr
:
my_data %>%
mutate(full_name = str_c(first_name, last_name, sep = " "))
# A tibble: 3 × 3
first_name last_name full_name
<chr> <chr> <chr>
1 Maria Svensson Maria Svensson
2 Mohammed Ayman Mohammed Ayman
3 Magnus Bentzel Magnus Bentzel
Genom att använda dplyr
får vi ren och enkel kod, utan att använda $
, []
, eller dylikt. Nya kolumner skapas med funktionen mutate().
Du kan klistra ihop fler än två strängar med str_c()
:
a = "Hej"
b = "jag"
c = "heter"
d = "Adam"
str_c(a, b, c, d, sep = " ")
[1] "Hej jag heter Adam"
8.1.7 Räkna antal matchningar i en sträng
Med str_count()
kan vi beräkna hur många gånger en viss sträng eller tecken förekommer i en sträng. Låt oss kontrollera hur många gånger bokstaven ‘m’ förekommer i förnamnen. Vi skapar en ny variabel som vi kallar antal_m
för detta:
my_data %>%
mutate(antal_m = str_count(first_name, 'm'))
# A tibble: 3 × 4
first_name last_name full_name antal_m
<chr> <chr> <chr> <int>
1 Maria Svensson Maria Svensson 0
2 Mohammed Ayman Mohammed Ayman 2
3 Magnus Bentzel Magnus Bentzel 0
R är skriftlägeskänsligt. Bokstaven m är inte ekvivalent med bokstaven M. Vi provar igen med bokstaven M:
my_data %>%
mutate(antal_m = str_count(first_name, 'M'))
# A tibble: 3 × 4
first_name last_name full_name antal_m
<chr> <chr> <chr> <int>
1 Maria Svensson Maria Svensson 1
2 Mohammed Ayman Mohammed Ayman 1
3 Magnus Bentzel Magnus Bentzel 1
8.1.8 Detektera strängar, tecken och symboler i strängar
Med funktionen str_detect()
kan vi avgöra om siffror, bokstäver, symboler, tecken eller strängar förekommer i en sträng. Funktionen str_detect()
returnerar ett booleskt värde (TRUE, FALSE). Vi skapar nu variabeln finns_m
som klargör om bokstaven "m"
finns i strängen:
my_data %>%
mutate(finns_m = str_detect(first_name, 'm'))
# A tibble: 3 × 4
first_name last_name full_name finns_m
<chr> <chr> <chr> <lgl>
1 Maria Svensson Maria Svensson FALSE
2 Mohammed Ayman Mohammed Ayman TRUE
3 Magnus Bentzel Magnus Bentzel FALSE
Med funktionerna string_ends()
och string_starts()
kan man avgöra om en sträng börjar eller slutar med ett viss sträng. Vi kontrollerar om strängen börjar med M och slutar med s. Vi skapar två nya variabler som indikerar detta:
my_data %>%
mutate(starts_M = str_starts(first_name, 'M'),
ends_s = str_ends(first_name, 's'))
# A tibble: 3 × 5
first_name last_name full_name starts_M ends_s
<chr> <chr> <chr> <lgl> <lgl>
1 Maria Svensson Maria Svensson TRUE FALSE
2 Mohammed Ayman Mohammed Ayman TRUE FALSE
3 Magnus Bentzel Magnus Bentzel TRUE TRUE
8.1.9 Ersätt strängar och tecken
Ersätt hela eller delar av en sträng med funktionen str_replace()
. Nu ersätter vi bokstaven M
med en asterix (*
):
my_data %>%
mutate(new_first_name = str_replace(first_name, 'M', '*'))
# A tibble: 3 × 4
first_name last_name full_name new_first_name
<chr> <chr> <chr> <chr>
1 Maria Svensson Maria Svensson *aria
2 Mohammed Ayman Mohammed Ayman *ohammed
3 Magnus Bentzel Magnus Bentzel *agnus
Funktionen str_replace()
ersätter bara den första instansen (förekomsten) av mönstret du söker. Använd funktionen str_replace_all()
för att ersätta alla instanser. Nedan ersätter vi alla m
med *
:
my_data %>%
mutate(new_first_name = str_replace_all(first_name, 'm', '*'))
# A tibble: 3 × 4
first_name last_name full_name new_first_name
<chr> <chr> <chr> <chr>
1 Maria Svensson Maria Svensson Maria
2 Mohammed Ayman Mohammed Ayman Moha**ed
3 Magnus Bentzel Magnus Bentzel Magnus
8.1.10 Ersätt NA med “NA”
Missing data är den engelska termen för information som saknas. Oftast används bara ordet missing för att referera till data som saknas. Missing betecknas med NA
(Not Available) i R. Vi kan skapa missing i en character-vektor genom att ange värdet till NA
utan citattecken:
x <- c("abc", NA)
x
[1] "abc" NA
Notera att strängen “abc” är omgiven av citattecken för att indikera att det är en sträng. NA är däremot inte omgivet av citattecken eftersom det är missing. Vi kan ersätta missing (NA
) med strängen NA (“NA"
).
x <- c("abc", NA)
str_replace_na(x)
[1] "abc" "NA"
8.1.11 Extrahera delar av strängar (substring)
Funktionen str_sub()
kan extrahera delar av strängar. Funktionen har argumenten start
och end
som indikerar var extraktionen börjar och slutar. Här extraherar vi första till andra positionen:
x <- c("Sommarlov")
str_sub(string=x, start=1, end=2)
[1] "So"
Som vanligt kan vi ange värden för argumenten string
, start
och end
utan att ange argumentens namn, förutsatt att vi anger värdena i rätt ordning:
x <- c("Sommarlov")
str_sub(x, 1, 2)
[1] "So"
Negativa start
och end
indikerar att extraktionen börjar i slutet av strängen. Här extraherar vi alla tecken från det näst sista till det sista:
x <- c("Sommarlov")
str_sub(x, -2, -1)
[1] "ov"
Om du försöker extrahera mer än vad som existerar i strängen kommer str_sub()
returnera så mycket som möjligt:
x <- c("Sommarlov")
str_sub(x, 1, 100)
[1] "Sommarlov"
8.2 Regular expressions (Regex)
I verkligheten kan du behöva göra ännu mer sofistikerade matchningar och då är regular expressions ovärderliga. Regular expressions (regex) är en sekvens av tecken som söker efter ett mönster i en sträng.
Andra resurser för regular expressions:
- https://www.regular-expressions.info/ ger detaljerad information om hur regular expressions fungerar.
- https://regex101.com är ett interaktivt verktyg som låter dig testa dina regular expressions live för att se om de beter sig som du förväntar dig.
Reular expressions kan vid första anblick verka komplicerade men när du förstått hur de fungerar kommer du inse att detta är extremt kraftfulla för att hantera strängar. Ofta krävs en del testande innan man har ett fungerande regular expression och för att se hur din regular expression matchar tecknen i en sträng finns funktionerna str_view()
och str_view_all()
. Dessa visar hur regular expressions matchar en sträng. Funktionerna markerar den delen av strängen som matchar din regular expression. Vi använder nu funktionen för att se om vår regular expression identifierar bokstaven X
i strängarna nedan. Strängen som skall genomsökas anges i argumentet string
och mönstret vi vill hitta anges i pattern
:
my_strings <- c("Xxx", "Yyy", "Xxx")
str_view(string=my_strings, pattern='X')
Lodstrecket (|
) betyder “eller”. Med lodstrecket kan vi leta efter olika tecken och endast ett av dessa behöver matchas. Nedan anger vi pattern='X|x'
vilket innebär att vi letar efter X
eller x
.
my_strings <- c("Xxx", "xXx")
str_view(string=my_strings, pattern='X|x')
Som framgår ovan matchades bara första X eller x, vilket beror på att vi använde str_view()
. Funktionen str_view_all()
kan matcha alla förekomster av en sträng. Exempel följer:
my_strings <- c("Xxx", "xXx")
str_view_all(string=my_strings, pattern='X|x')
Med funktionerna str_view()
och str_view_all()
kan du alltså se hur ett regular expression (regex) matchar en sträng. Här följer ett exempel där vi använder str_view()
för att undersöka om vår regular expression kan matcha H
i början av en sträng. Med regular expressions används ^
för att indikera begynnelsen av en sträng. För att matcha H i början av en sträng skrivs därför följande:
str_view(string='Hej', pattern='^H')
Det verkar som att vår regular expression matchar H, som förväntat.
Punkt (.
) är regular expression som matchar vilket tecken som helst. Nedan testar vi om vi kan matcha A.
med någon av flera strängar i en vektor:
my_strings <- c("A", "AB", "ABC")
str_view(my_strings, 'A.')
Den första strängen A
matchas inte eftersom det inte finns något tecken efter A
. Strängarna AB
och ABC
matchas eftersom de innehåller A följt av ytterligare ett tecken.
I nästa exempel har vi strängen X.X
som vi vill matcha exakt. Punkten ska inte behandlas som ett speciellt tecken utan matchas exakt. Om det bara hade varit en sträng kunde vi matchat på X\.X
men eftersom vi vill använda regex för att matcha behöver vi addera ytterligare en backslash \
vilket beror på att regex också använder denna symbol som escape-symbol. Därför behövs följande kod för att matcha X.X
exakt:
Om du istället vill matcha exakt “A.C” så måste escape (\
) användas, enligt följande:
my_strings <- c("X.X")
str_view(my_strings, "X\\.X")
Hur matchas \
i en sträng med regular expression? Först och främst måste \
tolkas som ett vanligt tecken (utan speciell funktion), vilket kräver ytterligare en \
. Vi börjar med att skriva ett förnamn och ett efternamn separerat med \\
. Detta borde ge en \
när vi skriver ut det med writeLines()
:
my_string <- "Monika \\ Svensson"
writeLines(my_string)
Monika \ Svensson
Vi behöver alltså två backslash (\\
) för att få en sträng med en backslash. För att skapa en regex behövs nu ytterligare en backslash per backslash. För att matcha en backslash i en sträng behövs alltså följande kod:
str_view(my_string, "\\\\")
Det innebär att eftersom regular expressions och strängar använder samma escape-symbol (\), så behövs dubbla escapes när du använder regular expressions för särskilda tecken och symboler. Det är möjligt att undvika escape på själva tecknet, och endast specificera escape för regular expression genom att använda raw()
. Detta står för raw vectors,
str_view(my_string, r"(\\)")
För att matcha en asterix (*
) gäller samma princip:
str_view(string=c("abc", "a.c", "a*c", "a c"), pattern="\\*")
Det finns fler regular expressions för att matcha i strängar och dessa kan kombineras. De är som följer:
Sequence | Matches |
---|---|
. | Any character except newline |
[xyz] | Any character listed between the brackets (x , y , and z in this example) |
[a-z] | Any character between a and z , inclusive |
[^xyz] | The opposite of [xyz] |
\d | ASCII digits (0 through 9, inclusive) |
\D | Anything except ASCII digits |
\s | ASCII spaces (space, tab, newline, carriage return, form feed) |
\S | Anything except ASCII spaces |
\w | The same as [0-9A-Za-z_] |
\W | Anything except the characters matched by \w |
[[:alnum:]] | The same as [0-9A-Za-z] |
[[:alpha:]] | The same as [A-Za-z] |
[[:ascii:]] | Any ASCII character |
[[:blank:]] | ASCII tab or space |
[[:cntrl:]] | ASCII/Unicode control characters |
[[:digit:]] | The same as [0-9] |
[[:graph:]] | All “graphical” (printable) ASCII characters |
[[:lower:]] | The same as [a-z] |
[[:print:]] | The same as [[:graph:]] |
[[:punct:]] | The same as [!-/:-@[-`{-~] |
[[:space:]] | The same as [\t\n\v\f\r ] |
[[:upper:]] | The same as [A-Z] |
[[:word:]] | The same as \w |
[[:xdigit:]] | The same as [0-9A-Fa-f] |
\pN | Unicode character class by using single-letter class names (“N” in this example) |
\p{Greek} | Unicode character class by unicode name (“Greek” in this example) |
\PN | The opposite of \pN |
\P{Greek} | The opposite of \p{Greek} |
xy | x followed immediately by y |
x\|y | either x or y , preferring x |
x* | zero or more x , preferring more |
x*? | zero or more x , preferring fewer |
x+ | one or more x , preferring more |
x+? | one or more x , preferring fewer |
x? | zero or one x , preferring one |
x?? | zero or one x , preferring zero |
x{n,m} | between n and m repetitions of x , preferring more |
x{n,m}? | between n and m repetitions of x , preferring fewer |
x{n,} | at least n repetitions of x , preferring more |
x{n,}? | at least n repetitions of x , preferring fewer |
x{n} | exactly n repetitions of x |
(x) | unnamed capture group for sub-pattern x |
(?P<name>x) | named capture group, named name , for sub-pattern x |
(?:x) | non-capturing sub-pattern x |
\* | Literal * for any punctuation character * |
\Q...\E | Literal ... for any text ... as long as it does not include literally \E |
8.3 Ankare (^, $)
Det finns även regular expressions som indikerar var matchingar skall ske. De vanligaste symbolerna är ^
som indikerar att matchning ska ske i början av en träng och $
som indikerar att matchning ska ske i slutet av strängen.
Sequence | Matches |
---|---|
^ | At the beginning of the given string |
$ | At the end of the given string |
\A | At the beginning of the given string |
\z | At the end of the given string |
\b | At an ASCII word boundary (transition between \w and either \W , \A or \z , or vice-versa) |
\B | Not at an ASCII word boundary |
8.3.1 Character set (class)
En character set
är en lista på tecken som skall matchas. Listan anges i []
. För att matcha på bokstäverna a, b eller c används följande character set: [abc]
. Character set är fördelaktigt eftersom man slipper specificera escape (\
) för regular expression symboler. Du behöver inte escape för följande symboler: $
.
|
?
*
+
(
)
[
{
. Det betyder att du kan skriva dessa symboler och matcha på dem direkt i character set (utan att specificera escape). För att matcha på ., , a b eller c används följande character set: [.*abc]
Det finns dock symboler som har speciell funktion även inuti character set och dessa är som följer:
]
^
negerar listan.[^abc]
matchar på allt förutom a, b och c.[a-zA-Z0-9]
matchar alla gemener, versaler och siffror
-
definierar ett intervall som följer alfabetisk eller numerisk ordning.- Exempel:
[a-d]
matchar bokstäverna a, b, c eller d. - Exempel:
[0-4]
matchar siffrorna 0, 1, 2, 3, 4
- Exempel:
\
används för att escape]
,^
och-
i en character set.[a\\-c]
matchara-c
.[\^\-]
matchar^-
.
Nu matchar strängar som börjar med a
och slutar med b
, och där emellan har antingen asterix (*
) eller bokstaven b
:
str_view(c("abc", "a.c", "a*c", "a c"), "a[*b]c")
Notera att vi lyckades matcha asterix (*
) utan att använda \\
, vilket förklaras av att vi istället använde []
vilket kallas character class. Låt oss prova igen men nu byter vi ut första a
mot vilket tecken som helst (.
):
str_view(c("abc", "a.c", "a*c", "a c"), ".[*]c")
För att matcha på mellanslag (blanksteg) kan man använda vanligt mellansteg, med eller utan character klass:
str_view(string=c("a c", "a.c", "a*c"), pattern="a[ ]c")
str_view(string=c("a c", "a.c", "a*c"), pattern="a c")
8.3.2 Alternerad matchning
Du kan matcha på flera alternativ genom att använda lodstrecket (|
), enligt följade:
str_view(c("a", "b", "c", "d"), "a|b")
Du kan matcha på fler än två alternativ:
str_view(c("a", "b", "c", "d"), "a|b|c")
Om du matchar inuti ett ord behövs parenteser, enligt följande:
str_view(c("glad", "glöd"), "gl(a|ö)d")
my_words <- c("Sommarlov", "Okidoki", "Tackar", "Bolag")
# Startar ordet med bokstaven S?
str_detect(my_words, "^S")
[1] TRUE FALSE FALSE FALSE
# Hur många ord slutar på bokstaven i eller r?
str_detect(my_words, "[ir]$")
[1] FALSE TRUE TRUE FALSE
str_subset(my_words, "x$")
character(0)
8.3.3 Negera mathning
Istället för att hitta alla strängar som innehåller en viss symbol kan vi negera matchningen. Detta kan göras genom att använda utropstecken (!
) framför str_detect()
. Utropstecken (!
) betyder “omvänt” eller “inte”. Det innebär att !str_detect()
betyder att en sträng inte kan matchas. Låt oss testa:
# Vilka ord börar inte med S?
my_words <- c("Sommarlov", "Okidoki", "Tackar", "Bolag")
!str_detect(my_words, "^S")
[1] FALSE TRUE TRUE TRUE
Du kan också negera matchning med hjälp av character klass. Detta göras genom att börja character klass med ^
. Med följande kod identifierar ord som inte börjar med S:
# Vilka ord börar inte med S?
my_words <- c("Sommarlov", "Okidoki", "Tackar", "Bolag")
str_detect(my_words, "^[^S]")
[1] FALSE TRUE TRUE TRUE
8.4 Repeterad matchning
Vi kan kontrollera antal gången en sträng kan matchas med följande tecken:
my_string <- "AAAAAA"
str_view(my_string, "AA?")
str_view(my_string, "AA+")
str_view(my_string, "AA*")
Med hakparenteser kan du specificera hur många gånger en matchning skall ske:
{n}
: n antal gånger{n,}
: n eller fler gånger{,m}
: maximalt m gånger{n,m}
: mellan n och m gånger
str_view(my_string, "A{2}")
str_view(my_string, "A{2,}")
str_view(my_string, "A{2,3}")
8.4.1 Shorthand character classes
Det finns character sets som förkortats eftersom de används så ofta. Dessa är som följer:
\d
: matchar vilken siffra som helst\D
: matchar allt som inte är en siffra\s
: matchar alla mellanrum (e.g. mellansteg, tab, radbrytning);\S
: matchar matchar allt som inte är mellanrum\w
: matchar alla siffror och bokstäver\W
: matchar allt som inte är siffra eller bokstav
I regular expressions ska de anges med en extra backslash. För \d
blir det således \\d
.
Låt oss matcha alla siffror respektive allt som inte är siffror:
str_view_all("Hej! 123456 @ # %", "\\d")
str_view_all("Hej! 123456 @ # %", "\\D")
Matcha alla bokstäver och siffror, respektive motsatsen.
str_view_all("Hej! 123456 @ # %", "\\w")
str_view_all("Hej! 123456 @ # %", "\\W")
Matcha alla mellanrum, respektive motsatsen.
str_view_all("Hej! 123456 @ # %", "\\s")
str_view_all("Hej! 123456 @ # %", "\\S")
Matcha alla sekvenser med 5 bokstäver eller siffror, eller 2 siffror:
str_view_all("Hej jag heter Maggi och har telefonnummer 123456", "\\w{5}|\\d{2}")
8.4.2 Operatörers prioritering
Vid matematiska beräkningar finns en prioritering för operander. Multiplikation går före addition och subtraktion. Beräkningen 1*2+3 kommer beräknas som (1*2)+3 eftersom multiplikation prioriteras. För regular expressions finns också priorteringar. Kvantifierar (exempelvis +) prioriteras högre än alterneringar (|). Om en regular expression ger ett oväntat resultat så kan priorteringen behöva förtydligas med hjälp av parenteser. Exempel följer:
# Mindre tydlig regular expression
str_view("Jag hittade en vattenkanna", "an+")
# Tydligare regular expression
str_view("Jag hittade en vattenkanna", "a(n+)")
8.4.3 Booleska matchingar och villkor
Du kan använda lodstrecket och & som vanligt även med strängar. Det betyder att dessa två kommandon är ekvivalenta:
# Skapa en vektor med ord
my_words <- c("hej", "bra", "ja", "kanske", "lite", "mycket", "troligen", "sannolikt", "utmärkt")
# Identifiera alla ord som innehåller "a" eller "b"
my_words[str_detect(my_words, "a") | str_detect(my_words, "b")]
[1] "bra" "ja" "kanske" "sannolikt"
# Identifiera alla ord som innehåller "a" eller "b"
my_words[str_detect(my_words, "a|b")]
[1] "bra" "ja" "kanske" "sannolikt"
Du kan på liknande sätta göra andra användbara villkor:
# Identifiera alla ord som innehåller "a" och "n" och "k"
my_words[str_detect(my_words, "a") & str_detect(my_words, "n") & str_detect(my_words, "k")]
[1] "kanske" "sannolikt"