Programujete-li aplikace v pokročilém měřítku, jistě jste se u nějakého skriptu zarazili a povzdechli si, jak by bylo vše jednoduché, kdyby bylo možné vkládat do SQL dotazů regulární výrazy. Využijete-li dnešního článku, můžete tento problém hodit za hlavu. Ukáži vám, jak s pomocí PHP posílat SQL dotazy s přímo vloženými regulárními výrazy MySQL a PostgreSQL serverům.

Článek předpokládá jistou znalost regulárních výrazů.

K čemu jsou vlastně regulární výrazy v SQL dobré? Představte si, že máte databázovou tabulku category, s poli id a title a těmito záznamy:

id title
1-1 title1
1-1-2 title2
1-2 title3

Pokud si budete chtít „vytáhnout“ jen záznamy, jejichž id začíná na ‚1-‚, ale následuje pouze další číslo, prakticky nemáte jinou šanci, než použít tento SQL dotaz s regulárním výrazem:

mysql_query("SELECT title FROM category WHERE id REGEXP \"^1-[[:digit:]]$\"");

V tomto případě Vám SQL server vrátí záznamy s id 1 a 3, záznam s id 2 nemá do konce řetězce pouze čísla, ale také pomlčku a ta se jako číslo nevyhodnocuje, proto tento záznam nebude součástí výsledku.

Tento příklad byl přímo použit v Internetovém bazaru, popsaném zde, na Intervalu. Teď si ale předvedeme, jaké možnosti použití regulárních výrazů máme v MySQL a PgSQL.

Vlastní použití v SQL

Tyto příklady lze (a vypadá to i lépe) vyřešit i bez pomocí regulárních výrazů, zde jsou pouze pro ukázku.

MySQL

MySQL řeknete, že chcete použít regulární výraz, frází REGEXP, kterou umístíte do dotazu místo operátoru v podmínce, resp. místo fráze LIKE:

mysql_query("SELECT pole1 FROM tabulka WHERE pole2 REGEXP \"^abc$\"");

Tento příklad vrátí z tabulky záznamy, jejichž pole2 OBSAHUJE řetězec ‚abc‘.

mysql_query("SELECT pole1 FROM tabulka WHERE pole2 NOT REGEXP \"^abc$\"");

Tento příklad vrátí z tabulky záznamy, jejichž pole2 NEOBSAHUJE řetězec ‚abc‘. MySQL NENÍ od verze 3.23.4 a vyšší citlivý na malá a velká písmena.

PostgreSQL

V PostgreSQL máme možnosti již větší, operátor značící použití regulárního výrazu se sice nachází na stejném místě jako v MySQL, nicméně může mít více podob:

pg_exec("SELECT pole1 FROM tabulka WHERE pole2 ~ ‚abc’");

Vrátí z tabulky záznamy, jejichž pole2 OBSAHUJE řetězec ‚abc‘. Regulární výraz JE citlivý na malá a velká písmena.

pg_exec("SELECT pole1 FROM tabulka WHERE pole2 !~ ‚abc’");

Vrátí z tabulky záznamy, jejichž pole2 NEOBSAHUJE řetězec ‚abc‘. Regulární výraz JE citlivý na malá a velká písmena.

pg_exec("SELECT pole1 FROM tabulka WHERE pole2 ~* ‚abc’");

Vrátí z tabulky záznamy, jejichž pole2 OBSAHUJE řetězec ‚abc‘. Regulární výraz NENÍ citlivý na malá a velká písmena.

pg_exec("SELECT pole1 FROM tabulka WHERE pole2 !~* ‚abc’");

Vrátí z tabulky záznamy, jejichž pole2 NEOBSAHUJE řetězec ‚abc‘. Regulární výraz NENÍ citlivý na malá a velká písmena.

Podívejme se na několik příkladů použití. Za pomlčkou vždy vidíte, jakou hodnotu server vrátí:

mysql_query("SELECT \"fofo\" REGEXP \"^fo$\"");    – 0
mysql_query("SELECT \"Baaan\" NOT REGEXP \"^Ba*n\"");    – 0
mysql_query("SELECT \"pipi\" REGEXP \"^(pi)*$\"");    – 1
pg_exec("SELECT \"abcde\" !~ ‚bc$’");    – 1
pg_exec("SELECT \"kuku\" ~* ‚^(KU)*$’");    – 1

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

3 Příspěvků v diskuzi

  1. Dobrý den,
    zaprvé článek byl myšlen jako rychlé prolítnutí regulárních výrazů a možností v MySQL a PgSQL a tento účel myslím splnil. Pokud bych chtěl tyto konstrukce použít a akorát nevěděl, „jak to tam přesně je“, tak by mi tento článek pomohl.
    Zadruhé nevím, jestli jste si všiml, ale článek je téměř 9 let starý, tudíž již opravdu out-of-date.
    Robert Bisom

  2. vůbec není out-of-date a vůbec není k ničemu, mě dneska pomohl při přejmenování záznamů v databázi, takže autorovi patří můj dík.

Odpovědět