R Language
Wyrażenia regularne (regex)
Szukaj…
Wprowadzenie
Wyrażenia regularne (zwane także „regex” lub „regexp”) definiują wzorce, które można dopasować do łańcucha . Wpisz ?regex
w oficjalnej dokumentacji R i zobacz Dokumenty Regex, aby uzyskać więcej informacji. Najważniejszym „gotcha”, którego nie nauczysz się w wyrażeniach regularnych / tematach SO, jest to, że większość funkcji R-regex wymaga użycia sparowanych ukośników odwrotnych, aby uciec w parametrze pattern
.
Uwagi
Klasy postaci
-
"[AB]"
może być A lub B. -
"[[:alpha:]]"
może być dowolną literą -
"[[:lower:]]"
oznacza każdą małą literę. Zauważ, że"[az]"
jest blisko, ale nie pasuje, np.ú
. -
"[[:upper:]]"
oznacza każdą wielką literę. Zauważ, że"[AZ]"
jest blisko, ale nie pasuje, np.Ú
. -
"[[:digit:]]"
oznacza dowolną cyfrę: 0, 1, 2, ... lub 9 i jest równoważne z"[0-9]"
.
Kwantyfikatory
+
, *
i ?
stosuj jak zwykle w wyrażeniach regularnych. - +
odpowiada co najmniej raz, *
odpowiada 0 lub więcej razy, a ?
dopasowuje 0 lub 1 raz.
Wskaźniki początku i końca linii
Możesz określić pozycję wyrażenia regularnego w ciągu:
-
"^..."
wymusza wyrażenie regularne na początku łańcucha -
"...$"
wymusza, aby wyrażenie regularne znajdowało się na końcu łańcucha
Różnice w stosunku do innych języków
Pamiętaj, że wyrażenia regularne w R często wyglądają nieco inaczej niż wyrażenia regularne używane w innych językach.
R wymaga ucieczki z podwójnym odwrotnym ukośnikiem (ponieważ
"\"
już zwykle oznacza ucieczkę w ciągach R), więc na przykład, aby uchwycić białe znaki w większości silników wyrażeń regularnych, wystarczy wpisać\s
, a\\s
w R .Znaki UTF-8 w R powinny być
[\U{1F600}]
U, np.[\U{1F600}]
i[\U1F600]
pasują do 😀, podczas gdy w, np. Ruby, byłoby to dopasowane małą literą u.
Dodatkowe zasoby
Poniższa witryna reg101 jest dobrym miejscem do sprawdzenia wyrażenia regularnego online przed użyciem R-skryptu.
Wikibook R Programowanie ma stronę poświęconą przetwarzaniu tekstu z wieloma przykładami wykorzystującymi wyrażenia regularne.
Eliminowanie białych znaków
string <- ' some text on line one;
and then some text on line two '
Przycinanie białych znaków
„Przycinanie” białych znaków zwykle odnosi się do usuwania zarówno początkowych, jak i końcowych białych znaków z łańcucha. Można to zrobić za pomocą kombinacji poprzednich przykładów. gsub
służy do wymuszenia zamiany zarówno na mecze wiodące, jak i końcowe.
Przed R 3.2.0
gsub(pattern = "(^ +| +$)",
replacement = "",
x = string)
[1] "some text on line one; \nand then some text on line two"
R 3.2.0 i wyższe
trimws(x = string)
[1] "some text on line one; \nand then some text on line two"
Usuwanie wiodących białych znaków
Przed R 3.2.0
sub(pattern = "^ +",
replacement = "",
x = string)
[1] "some text on line one; \nand then some text on line two "
R 3.2.0 i wyższe
trimws(x = string,
which = "left")
[1] "some text on line one; \nand then some text on line two "
Usuwanie końcowych białych znaków
Przed R 3.2.0
sub(pattern = " +$",
replacement = "",
x = string)
[1] " some text on line one; \nand then some text on line two"
R 3.2.0 i wyższe
trimws(x = string,
which = "right")
[1] " some text on line one; \nand then some text on line two"
Usuwanie wszystkich białych znaków
gsub(pattern = "\\s",
replacement = "",
x = string)
[1] "sometextonlineone;andthensometextonlinetwo"
Pamiętaj, że spowoduje to również usunięcie znaków białych znaków, takich jak tabulatory ( \t
), znaki nowej linii ( \r
i \n
) i spacje.
Sprawdź poprawność daty w formacie „RRRRMMDD”
Powszechną praktyką jest nazywanie plików przy użyciu daty jako prefiksu w następującym formacie: YYYYMMDD
, na przykład: 20170101_results.csv
. Datę w takim formacie ciągu można zweryfikować za pomocą następującego wyrażenia regularnego:
\\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])
Powyższe wyrażenie uwzględnia daty od roku: 0000-9999
, miesiące od: 01-12
do dni 01-31
.
Na przykład:
> grepl("\\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])", "20170101")
[1] TRUE
> grepl("\\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])", "20171206")
[1] TRUE
> grepl("\\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])", "29991231")
[1] TRUE
Uwaga : sprawdza poprawność składni daty, ale możemy mieć niepoprawną datę z prawidłową składnią, na przykład: 20170229
(2017 r. Nie jest rokiem przestępnym).
> grepl("\\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])", "20170229")
[1] TRUE
Jeśli chcesz sprawdzić datę, możesz to zrobić za pomocą tej funkcji zdefiniowanej przez użytkownika:
is.Date <- function(x) {return(!is.na(as.Date(as.character(x), format = '%Y%m%d')))}
Następnie
> is.Date(c("20170229", "20170101", 20170101))
[1] FALSE TRUE TRUE
Sprawdź poprawność skrótów pocztowych w Stanach Zjednoczonych
Poniższy regex
obejmuje 50 stanów, a także Commonwealth / Territory (patrz www.50states.com ):
regex <- "(A[LKSZR])|(C[AOT])|(D[EC])|(F[ML])|(G[AU])|(HI)|(I[DLNA])|(K[SY])|(LA)|(M[EHDAINSOT])|(N[EVHJMYCD])|(MP)|(O[HKR])|(P[WAR])|(RI)|(S[CD])|(T[NX])|(UT)|(V[TIA])|(W[AVIY])"
Na przykład:
> test <- c("AL", "AZ", "AR", "AJ", "AS", "DC", "FM", "GU","PW", "FL", "AJ", "AP")
> grepl(us.states.pattern, test)
[1] TRUE TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE
>
Uwaga :
Jeśli chcesz zweryfikować tylko 50 stanów, zalecamy użycie zestawu danych R: state.abb
from state
, na przykład:
> data(state)
> test %in% state.abb
[1] TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE
Otrzymujemy TRUE
tylko dla skrótów 50-stanowych: AL, AZ, AR, FL
.
Sprawdź poprawność numerów telefonów w USA
Następujące wyrażenie regularne:
us.phones.regex <- "^\\s*(\\+\\s*1(-?|\\s+))*[0-9]{3}\\s*-?\\s*[0-9]{3}\\s*-?\\s*[0-9]{4}$"
Sprawdza numer telefonu w postaci: +1-xxx-xxx-xxxx
, w tym opcjonalne początkowe / końcowe spacje na początku / końcu każdej grupy numerów, ale nie w środku, na przykład: +1-xxx-xxx-xx xx
jest niepoprawny. -
ogranicznik może być zastąpiony przez półfabrykatów: xxx xxx xxx
lub bez ogranicznika: xxxxxxxxxx
. Prefiks +1
jest opcjonalny.
Sprawdźmy to:
us.phones.regex <- "^\\s*(\\+\\s*1(-?|\\s+))*[0-9]{3}\\s*-?\\s*[0-9]{3}\\s*-?\\s*[0-9]{4}$"
phones.OK <- c("305-123-4567", "305 123 4567", "+1-786-123-4567",
"+1 786 123 4567", "7861234567", "786 - 123 4567", "+ 1 786 - 123 4567")
phones.NOK <- c("124-456-78901", "124-456-789", "124-456-78 90",
"124-45 6-7890", "12 4-456-7890")
Ważne przypadki:
> grepl(us.phones.regex, phones.OK)
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE
>
Nieprawidłowe przypadki:
> grepl(us.phones.regex, phones.NOK)
[1] FALSE FALSE FALSE FALSE FALSE
>
Uwaga :
-
\\s
zestawienia dowolnego miejsca, zakładka lub znak nowego wiersza
Uciekające postacie we wzorach regularnych R.
Ponieważ zarówno R, jak i wyrażenie regularne dzielą znak zmiany znaczenia, "\"
, budowanie poprawnych wzorców dla grep
, sub
, gsub
lub dowolnej innej funkcji, która akceptuje argument wzorca, często wymaga parowania ukośników odwrotnych. Jeśli zbudujesz trzyelementowy wektor znaków, w którym jeden element ma linię, inny znak tabulacji, a drugi żaden, a pragnieniem jest przekształcenie albo linii albo tabulacji w 4-spacje, wówczas potrzebna jest pojedyncza kreska odwrotna, ale zmienne ukośniki odwrotne do dopasowania:
x <- c( "a\nb", "c\td", "e f")
x # how it's stored
# [1] "a\nb" "c\td" "e f"
cat(x) # how it will be seen with cat
#a
#b c d e f
gsub(patt="\\n|\\t", repl=" ", x)
#[1] "a b" "c d" "e f"
Zauważ, że argument wzorca (który jest opcjonalny, jeśli pojawia się jako pierwszy i wymaga tylko częściowej pisowni) jest jedynym argumentem wymagającym tego podwojenia lub parowania. Argument zamiany nie wymaga podwojenia znaków, które wymagają zmiany znaczenia. Jeśli chcesz, aby wszystkie przejścia między wierszami i wystąpienia 4-spacji zostały zastąpione tabulatorami, byłoby to:
gsub("\\n| ", "\t", x)
#[1] "a\tb" "c\td" "e\tf"
Różnice między wyrażeniami regularnymi Perl i POSIX
Istnieją dwa bardzo nieznacznie różne silniki wyrażeń regularnych zaimplementowane w R. Domyślnie jest to zgodne z POSIX; wszystkie funkcje wyrażenia regularnego w R są również wyposażone w opcję włączenia tego drugiego typu: perl = TRUE
.
Patrząc w przyszłość / patrz w przeszłość
perl = TRUE
włącza przewidywanie i odwracanie w wyrażeniach regularnych.
-
"(?<=A)B"
odpowiada wyglądzie literyB
tylko wtedy, gdy poprzedza jąA
, tzn."ABACADABRA"
byłoby dopasowane, ale"abacadabra"
i"aBacadabra"
nie.