MySQL Wyrażenia regularne (Regexp)
⚡ Inteligentne podsumowanie
MySQL Wyrażenia regularne (REGEXP) dopasowują wartości kolumn do elastycznych wzorców, których nie można wyrazić za pomocą symboli wieloznacznych. Wyjaśniono składnię REGEXP, synonim RLIKE, wszystkie obsługiwane metaznaki, poprawione przykłady zapytań do bazy danych myflixdb oraz funkcje wyrażeń regularnych dodane w MySQL 8.0.
Jakie są MySQL wyrażenia regularne?
MySQL wyrażenia regularne Pomagają wyszukiwać dane spełniające złożone kryteria. Wyrażenie regularne to wzorzec opisujący kształt poszukiwanej wartości, a nie samą wartość.
Jeśli już współpracowałeś z MySQL symbole wieloznaczneMożesz zapytać, dlaczego warto uczyć się wyrażeń regularnych, skoro LIKE daje podobne rezultaty. Odpowiedź brzmi: siła ekspresji: symbole wieloznaczne oferują tylko dwa symbole, podczas gdy wyrażenia regularne opisują zakresy znaków, alternatywy, powtórzenia i pozycje słów w jednym wzorcu.
Mając zamierzony cel, w następnej sekcji przedstawiono składnię, której należy używać w każdym zapytaniu REGEXP.
Podstawowa składnia REGEXP
Podstawowa składnia wyrażenia regularnego jest następująca.
SELECT * FROM table_name WHERE fieldname REGEXP 'pattern';
TUTAJ:
- „Instrukcja SELECT” jest standardem SELECT oświadczenie.
- „WHERE nazwa pola” jest nazwą kolumny, na której wykonywane jest wyrażenie regularne.
- „Wzorzec” REGEXP” — REGEXP jest operatorem wyrażenia regularnego, a „pattern” reprezentuje wzorzec, który ma zostać dopasowany. RLIKE jest synonim REGEXP i zwraca te same wyniki. Aby nie pomylić go z operatorem LIKE, lepiej użyć REGEXP.
Przyjrzyjmy się teraz praktycznemu przykładowi.
SELECT * FROM `movies` WHERE `title` REGEXP 'code';
Powyższe zapytanie wyszukuje wszystkie tytuły filmów zawierające słowo „code”. Nie ma znaczenia, czy „code” pojawia się na początku, w środku czy na końcu tytułu. Jeśli tytuł zawiera wzorzec, wiersz jest zwracany.
Dopasowywanie początku wartości do listy znaków
Załóżmy, że chcemy znaleźć filmy, których tytuły zaczynają się od a, b, c lub d, po których następuje dowolna liczba innych znaków. Łączymy listę znaków z metaznakiem daszka, aby uzyskać ten rezultat.
SELECT * FROM `movies` WHERE `title` REGEXP '^[abcd]';
Wykonanie powyższego skryptu w MySQL Workbench w stosunku do bazy danych myflixdb daje nam następujące wyniki.
| identyfikator_filmu | tytuł | dyrektor | rok_wydania | identyfikator_kategorii |
|---|---|---|---|---|
| 4 | Code Imię Czarny | Edgara Jimza | 2010 | NULL |
| 5 | Małe dziewczynki tatusia | NULL | 2007 | 8 |
| 6 | Anioły i demony | NULL | 2007 | 6 |
| 7 | Davinci Code | NULL | 2007 | 6 |
W przypadku wzorca „^[abcd]” znak kursora (^) wymaga, aby dopasowanie rozpoczynało się od początku wartości, a lista znaków [abcd] akceptuje tylko tytuły, których pierwsza litera to a, b, c lub d. Porównanie nie uwzględnia wielkości liter w domyślnym sortowaniu, dlatego „Code Zwracana jest nazwa „Czarny”.
Wykluczanie znaków z negowaną listą znaków
Zmodyfikujmy teraz skrypt i zanegujmy listę znaków, aby zobaczyć, które wiersze zostaną zwrócone.
SELECT * FROM `movies` WHERE `title` REGEXP '^[^abcd]';
Wykonanie powyższego skryptu w MySQL Workbench i baza danych myflixdb dają nam następujące wyniki.
| identyfikator_filmu | tytuł | dyrektor | rok_wydania | identyfikator_kategorii |
|---|---|---|---|---|
| 1 | Piraci z Karaibów 4 | Rob Marshall | 2011 | 1 |
| 2 | Zapominając o Sarah Marshal | Nicholas Stoller | 2008 | 2 |
| 3 | X-Men | 2008 | ||
| 9 | Honey mooners | Jana Schultza | 2005 | 8 |
| 16 | 67% winnych | 2012 | ||
| 17 | Dyktator | Chalie Chaplie | 1920 | 7 |
| 18 | przykładowy film | Anonimowy | 8 | |
| 19 | film 3 | John Brown | 1920 | 8 |
Wewnątrz listy znaków znak akcentu zmienia znaczenie: „^[^abcd]” nadal zakotwicza dopasowanie na początku, podczas gdy [^abcd] wyklucza teraz każdy tytuł, który zaczyna się od jednego z zawartych znaków.
Te dwa przykłady wykorzystują tylko kotwice i listy znaków. Następna sekcja omawia pełny zestaw metaznaków.
Metaznaki wyrażeń regularnych
Powyższe przykłady przedstawiają najprostszą formę wyrażenia regularnego. Metaznaki pozwalają na precyzyjne dostrojenie wyszukiwania wzorców: wyrażają powtórzenia, alternatywy, zakresy i pozycje. Poniższa tabela zawiera listę wszystkich metaznaków obsługiwanych przez MySQL Operator REGEXP z poprawionym przykładem dla każdego z nich.
| Zwęglać | OPIS | Przykład | |
|---|---|---|---|
| * | gwiazdka (*) dopasowuje zero (0) lub więcej wystąpień pojedynczy znak który go poprzedza. | WYBIERZ * Z filmów GDZIE tytuł REGEXP 'da*'; pasuje do litery „d”, po której następuje zero lub więcej znaków „a”, więc Da Vinci Code i Daddy's Little Girls kwalifikują się. Użyj „da+”, gdy litera „a” musi być obecna. | |
| + | więcej (+) dopasowuje jedno lub więcej wystąpień znaku, który go poprzedza. | WYBIERZ * Z `filmów` WHERE `tytuł` REGEXP 'mon+'; Wyświetla wszystkie filmy zawierające „mon” i jeden lub więcej znaków „n”. Na przykład „Anioły i demony”. | |
| ? | znak zapytania (?) dopasowuje zero (0) lub jedno wystąpienie znaku, który go poprzedza. | WYBIERZ * Z `kategorii` GDZIE `nazwa_kategorii` REGEXP 'com?'; Dopasowuje „co” z opcjonalnym „m”. Na przykład: komedia i komedia romantyczna. | |
| . | kropka (.) Zastępuje dowolny pojedynczy znak za wyjątkiem nowej linii. | WYBIERZ * Z filmów GDZIE `rok_wydania` REGEXP '200.'; Wyświetla wszystkie filmy wydane w danym roku, zaczynające się od „200”, po którym następuje dowolny znak. Na przykład 2005, 2007, 2008. | |
| [ABC] | lista znaków [abc] Zastępuje dowolny z zawartych znaków. | WYBIERZ * Z `filmów` GDZIE `tytuł` REGEXP '[vwxyz]'; Wyświetla wszystkie filmy zawierające dowolną postać z „vwxyz”. Na przykład X-Men i Da Vinci. Code. | |
| [^ abc] | lista negowana [^abc] pasuje do dowolnego znaku oprócz zawartych w nim znaków. | WYBIERZ * Z `filmów` GDZIE `tytuł` REGEXP '^[^vwxyz]'; zwraca wszystkie filmy, których tytuł nie zaczyna się od znaku „vwxyz”. | |
| [AZ] | zakres [AZ] pasuje do dowolnej wielkiej litery. | SELECT * FROM `członkowie` WHERE `adres_pocztowy` REGEXP '[AZ]'; wyświetla wszystkich członków, których adres pocztowy zawiera literę od A do Z. Na przykład Janet Jones z numerem członkowskim 1. | |
| [az] | zakres [az] pasuje do dowolnej małej litery. | WYBIERZ * Z `członków` WHERE `adres_pocztowy` REGEXP '[az]'; zwraca wszystkich członków, których adres pocztowy zawiera literę od a do z. Należy pamiętać, że domyślne sortowanie nie uwzględnia wielkości liter, więc ten zakres obejmuje również wielkie litery. | |
| [0-9] | zakres [0-9] zastępuje dowolną cyfrę od 0 do 9. | WYBIERZ * Z `członkowie` GDZIE `numer_kontaktu` WYRAŻENIE_REGEXP '[0-9]'; Podaje wszystkich członków, których numer kontaktowy zawiera co najmniej jedną cyfrę. Na przykład Robert Phil. | |
| ^ | karetka (^) zakotwicza dopasowanie na początku wartości. | WYBIERZ * Z `filmów` GDZIE `tytuł` REGEXP '^[cd]'; Wyświetla wszystkie filmy, których tytuł zaczyna się na „c” lub „d”. Na przykład: Code Imię Black, Córeczki tatusia i Da Vinci Code. | |
| $ | znak dolara ($) zakotwicza dopasowanie na końcu wartości. | SELECT * FROM `filmy` WHERE `tytuł` REGEXP 'kod$'; Wyświetla wszystkie filmy, których tytuł kończy się na „kod”. Na przykład „Da Vinci” Code. | |
| | | pionowy pasek (|) izoluje alternatywy. | WYBIERZ * Z `filmów` GDZIE `tytuł` REGEXP '^[cd]|^[u]'; Wyświetla wszystkie filmy, których tytuł zaczyna się na „c”, „d” lub „u”. Na przykład: Code Imię Black, Da Vinci Codei Podziemia – Awakening. | |
| \b | granica słowa (\b) dopasowuje początek lub koniec słowa. Zastępuje starsze znaczniki [[:<:]] i [[:>:]], które MySQL Usunięto wersję 8.0. | SELECT * FROM `filmy` WHERE `tytuł` REGEXP '\\bfor'; Podaje wszystkie filmy, których słowo zaczyna się na „for”. Na przykład „Forgetting Sarah Marshall”. MySQL 5.7 odpowiednikiem jest '[[:<:]]for'. | |
| [[:klasa:]] | klasa postaci dopasowuje nazwaną grupę znaków: [[:alpha:]] dla liter, [[:space:]] dla białych znaków, [[:punct:]] dla znaków interpunkcyjnych i [[:upper:]] dla wielkich liter. Należy pamiętać, że Podwójna nawiasy kwadratowe. | WYBIERZ * Z `filmy` GDZIE `tytuł` WYRAŻENIE REGULAMINOWE '^[[:alpha:][:space:]]+$'; Wyświetla wszystkie filmy, których tytuł zawiera wyłącznie litery i spacje. Na przykład „Forgetting Sarah Marshal”, podczas gdy „Piraci z Karaibów 4” są pomijani ze względu na cyfrę. | |
Ukośnik odwrotny (\) jest znakiem ucieczki. Ponieważ MySQL najpierw analizuje ciąg, a następnie wzorzec, a literalny ukośnik odwrotny musi zostać zapisany jako podwójny ukośnik odwrotny (\\) wewnątrz wzorca REGEXP.
⚠️ Ostrzeżenie dotyczące wersji: MySQL Wersja 8.0.4 zastąpiła stary silnik wyrażeń regularnych biblioteką ICU. Znaczniki słów [[:<:]] i [[:>:]] zostały usunięte w tej wersji, więc wzorce skopiowane ze starszego materiału nie działają z „błędem składni” w MySQL 8.0. Zamiast tego użyj \b.
Teraz, gdy zdefiniowano każdy metaznak, pojawia się słuszne pytanie: kiedy REGEXP powinien zastąpić prostszy operator LIKE?
REGEXP czy LIKE: którego powinieneś użyć?
Oba operatory filtrują wiersze według wzorca, ale rozwiązują różne problemy. LIKE rozumie tylko dwa symbole, podczas gdy REGEXP rozumie cały zestaw metaznaków pokazany powyżej. Ta moc ma swoją cenę, więc wybór jest raczej kompromisem niż preferencją.
| Kryterium | LIKE | REGEXP |
|---|---|---|
| Symbole wzorców | tylko % i _ | Anchors, zakresy, przemienność, kwantyfikatory, klasy znaków |
| Typowe zastosowanie | Wyszukiwania prefiksów, sufiksów i „zawiera” | Walidacja, wiele alternatyw, dopasowywanie uwzględniające pozycję |
| Wykorzystanie indeksu | Możliwe, gdy wzór nie zaczyna się od % | Nigdy nie używa indeksu |
| Wartość zwracana | Prawda czy fałsz | 1 lub 0 oraz NULL, gdy którykolwiek z operandów ma wartość NULL |
Wybierz LIKE, aby uzyskać proste dopasowanie, ponieważ dobrze się czyta i nadal można użyć indeksu. Wybierz REGEXP, gdy jeden wzorzec musi wyrażać kilka reguł jednocześnie, na przykład „zaczyna się od c lub d i kończy cyfrą”. W przypadku dużych tabel najpierw zawęź wiersze za pomocą warunku indeksowanego, a następnie zastosuj REGEXP do tego mniejszego zbioru.
MySQL 8.0 funkcje wyrażeń regularnych
Operator REGEXP odpowiada tylko na jedno pytanie: czy wartość pasuje do wzorca? MySQL Wersja 8.0 dodała cztery funkcje, które wykraczają poza standardowe funkcje i pozwalają na lokalizację, np.tract i przepisz pasujący tekst. Każdy z nich akceptuje opcjonalny argument match_type, gdzie „c” wymusza porównanie uwzględniające wielkość liter, a „i” wymusza porównanie bez uwzględniania wielkości liter.
- REGEXP_LIKE(wyrażenie, wzór) Zwraca 1, gdy wartość pasuje do wzorca. Jest to forma funkcyjna operatora REGEXP, a argument match_type wyraźnie określa wielkość liter.
- REGEXP_INSTR(wyrażenie, wzorzec) zwraca pozycję pierwszego znaku dopasowania lub 0, jeśli wzorzec nie zostanie znaleziony.
- REGEXP_SUBSTR(wyrażenie, wzorzec) zwraca sam pasujący podciąg, co jest przydatne do wyodrębnienia roku, kodu lub liczby z dłuższej wartości tekstowej.
- REGEXP_REPLACE(wyrażenie, wzorzec, zastąpienie) zwraca wartość z każdym zastąpionym dopasowaniem, dzięki czemu może wyczyścić dane w środku Zapytanie SQL UPDATE.
SELECT title, REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title FROM `movies` WHERE REGEXP_LIKE(title, '[0-9]');
Powyższe zapytanie zwraca każdy tytuł filmu zawierający cyfrę, wraz z samymi cyframi. MySQL 5.7 te funkcje są niedostępne, więc operator REGEXP pozostaje jedyną opcją.

