PHP regulárne výrazy resp. regulárne výrazy (vzory)

  • 02.06.2019

) Ukázal som vám príklad použitia regulárnych výrazov na nájdenie určitých častí zdrojového kódu stránky. Teraz sa naučíme, ako ich napísať sami. Táto zručnosť vám pomôže písať, vyčistiť text od nepotrebných fragmentov, hľadať správne časti vo veľkých objemoch textu atď.

Táto téma je pomerne komplikovaná, ale pokúsim sa stručne zdôrazniť najdôležitejšie body. Neviem, ako uspejem, ale dúfam, že lekcia bude užitočná.
Začnime teda tým, že v PHP existuje viacero funkcií na prácu s regulárnymi výrazmi, no najčastejšie sa používajú tri:

  • preg_replace - vyhľadávanie a nahradenie textu, ktorý sa zhoduje s regulárnym výrazom;
  • preg_match - len vyhľadávanie regulárnych výrazov;
  • preg_split - vyhľadávanie a rozdelenie textu.

Aspoň v predchádzajúcich lekciách sme ich používali. Alebo skôr namiesto preg_match tam bol preg_match_all, ale to je v podstate to isté, len to druhé nepreruší vyhľadávanie po prvom nájdení. To znamená, že ak použijeme preg_match, nenájdeme všetky výskyty, ale iba prvý.

Výber funkcie, ktorá sa má použiť v ktorej situácii, je pomerne jednoduchý. Potrebujeme nahradiť - používame nahradiť, ako v prípade, keď sme potrebovali odstrániť nepotrebné časti kódu stránky, pamätáte?

$page = preg_replace("/ ^]/i", "", $strana); $strana = preg_replace("/ ^]/i", "", $strana); $strana = str_replace("", "", $strana);

Prvým parametrom funkcie je regulárny výraz, ktorý určuje, čo hľadáme. Druhým je to, čím ho nahradíme. Po tretie – Kde hľadáme. Preto sme tu vzali premennú $page a priradili sme jej výsledok funkcie preg_replace, kde sme hľadali všetky input type=checkboxy, ako aj otváracie a zatváracie označenia. Nahradili sme ich „, to znamená, že ich jednoducho vymazali. Dúfam, že tu je všetko jasné. K rozboru samotného výrazu (prvý parameter funkcie) prejdeme o niečo neskôr.
Bol tam aj príklad s použitím preg_match_all, ktorý prišiel vhod na nájdenie všetkých odkazov v zostávajúcom texte. Vtedy sme potrebovali odkazy, pretože obsahovali kľúčové slová, ktoré sme analyzovali. Tu je to, čo sa stalo:

Preg_match_all("/ ]+?>(.*?)<\/a>/uis",$strana,$ok); pre ($j=0; $j ".$ok[$j].""; }

Opäť platí, že prvým parametrom je regulárny výraz na nájdenie všetkých odkazov, ktoré sú, samozrejme, uzavreté v značke „a“ (ak nie ste priatelia s html značkami, prečítajte si ho). Druhá je premenná, ktorá obsahuje text, ktorý sa bude hľadať. Tretím parametrom je premenná, do ktorej je umiestnený výsledok — $ok. Potom už zostáva len prejsť všetky potrebné prvky $ok, aby sme získali kľúčové slová, ktoré potrebujeme. Samostatne treba povedať, že na výstupe dostaneme viacrozmerné pole. Preto to vypisujeme tak komplikovane: $ok[$j]. Ak chcete vidieť štruktúru poľa, použite funkciu nižšie a všetko pochopíte.

Print_r($ok);

Zdá sa, že sme prišli na funkcie, ktoré sme použili na prácu. Teraz zostáva len naučiť sa písať tie isté regulárne výrazy, ktoré sú prvým parametrom každej z týchto metód. Prejdime k tomu najdôležitejšiemu.

Ako písať regulárne výrazy

Najprv sa pozrime na hlavné štruktúry. Výrazy majú možnosti. Sú špecifikované jedným písmenom a píšu sa na konci, pred ktorým je lomka.

Okrem toho sú podporované nasledujúce metaznaky:

Metaznaky môžu mať modifikátory:

No a teraz môžeme prejsť k analýze našich regulárnych výrazov z minulej lekcie. Na základe vyššie uvedených tabuliek sa pokúsme pochopiť, čo máme. Tu je výraz:

/^]/i

Prvá a posledná lomka „/“ označujú, že sa v nich nachádza regulárny výraz. Zároveň za posledným vložíme „i“, je to možnosť, ako v prvej tabuľke - nerozlišovať veľké a malé písmená. Vo vnútri lomiek je samotný regulárny výraz. Začína sa znakom menej ako a vstupným tagom a potom všetko, kým bodka nie je obyčajný text, ktorý treba hľadať. Ale samotná bodka a postavy po nej - to je už zaujímavejšie. V tomto prípade ".*?" znamená ľubovoľnú postupnosť znakov. To znamená, že ak skombinujeme len text a túto konštrukciu, vyberieme celý text po prvom výskyte až do konca. Ak chcete zastaviť, musíte splniť buď koncovú html značku "väčšie ako" alebo znak nového riadku. Tento dizajn nám dáva takúto príležitosť:

Znaky v hranatých zátvorkách sú akoby spojené logickým ALEBO. Koniec je znamienko väčšie ako ALEBO začiatok riadku.
To je celý výraz, v ňom nastavíme počiatočnú podmienku, strednú a koncovú podmienku. Nie je to ťažké, však? Tu je ilustrácia, aby to bolo jasnejšie:

Poďme si to rozobrať ešte jednou vecou, ​​aby bolo všetko jasné. Hľadali sme na ne odkazy:

/]+?>(.*?)<\/a>/uis

Čítame výraz. Opäť najskôr zahodíme lomky a možnosti. Príznaky "uis" sú samovysvetľujúce, s výnimkou "u", ktoré som neopísal - naznačuje, že používame kódovanie Unicode. Veľa toho nezostalo. Začiatkom je značka „a“, ktorá sa otvorí, potom prichádza trieda

čo znamená NIE viac ani menej (otváranie a zatváranie html značiek), teda v tomto prípade ľubovoľné znaky. K triede sa pridá "+?", čo znamená, že táto trieda bude prítomná 1 alebo viackrát (ale aspoň 1 krát určite). A potom prichádza záverečná html značka pre značku „a“. Vo vnútri odkazu je text, ktorý nastavuje skupina

Nevieme predsa, aký tam bude text, tak definujeme takúto skupinu. A na konci záverečnej značky "a":

Všimnite si, že lomku ukončíme spätnou lomkou, aby vyzerala ako obyčajný text.

Fuj. Téma je naozaj dosť zložitá, chce to prax. Možno robím niečo nie úplne optimálne a vy dokážete robiť iné, správnejšie regulárne výrazy, ale ja som taký istý samouk ako vy, preto nesúďte striktne, radšej sa podeľte o svoje možnosti v komentároch. Ak niečo nie je jasné, komentáre a kontaktná stránka sú vám k dispozícii.

Regulárne výrazy sú veľmi výkonný, no zároveň ťažko pochopiteľný nástroj na spracovanie reťazcov. Popíšem hlavné body. Regulárny výraz je vzor reťazca. Podľa tejto šablóny môžete vyhľadávať výskyty, vykonávať náhradu, kontrolovať súlad so šablónou.

Pravidlá pre zostavenie šablóny (vzoru)

Hranice vzoru musia byť označené určitými znakmi, často pomocou " / ", ale radšej používam " # " pretože množstvo lomiek dopredu / dozadu sa môže nabíjať v očiach a "mriežky" sa zvyčajne nikde inde nepoužívajú. Takže: " #HereRegularExpressionBody#"

Vo vnútri regulárneho výrazu sa používajú zátvorky – ide o podvýrazy, s ktorými možno manipulovať, napríklad:

#^/catalog/(+)/(+)\.html.*#

Tento výraz je určený na príjem parametrov v reťazci URL. Na začiatku riadku je špeciálny znak " ^ " - to znamená začiatok riadku. Nasleduje " /katalóg/" - nie sú tu žiadne špeciálne znaky, je to len text, ktorý by mal byť obsiahnutý v riadku. Potom sme sa stretli so zátvorkami, čiže sme sa dostali k prvému podvýrazu. Hranaté zátvorky označujú množinu znakov, ktoré môžu byť v riadku na toto miesto. Podpíšte sa - " znamená enumeráciu. Podpísať " \ " uniká špeciálnym znakom. V prvom podvýraze teda môžeme mať VEĽKÉ a malé písmená latinskej abecedy, čísla od 0 do 9, podčiarkovník, pomlčku a bodku. Pomlčka a bodka sú špeciálne znaky, ale sú escapované, takže tu sú to len znaky. Po hranatých zátvorkách nasleduje znak " + " - to znamená, že predchádzajúci znak (a túto množinu znakov uvádzame v hranatých zátvorkách) môže ísť raz alebo viackrát. Potom príde " / "je len znak a podobný druhý podvýraz. Potom príde" \.html"čo znamená text" .html". A potom špeciálne znaky" .* " Bodka znamená ľubovoľný znak a hviezdička akékoľvek číslo predchádzajúceho znaku. To znamená, že za " .html„Všetko môže ísť.

Špecifikovanie množstva, kvantifikátory

Vyššie sme už uvažovali o takých symboloch označujúcich počet predchádzajúcich symbolov, ako napr + a * . Tu sú všetky možnosti určenia množstva:

Špeciálne znaky

Pre niektoré skupiny znakov existujú špeciálne skratky:

"chamtivosť"

Zvážte koncept chamtivosti regulárneho výrazu. Napríklad existuje riadok:

#()#

Čítanie: podvýraz:

Všetko sa zdá byť správne, podvýraz zapadá pod:

Ale pasuje aj na:

Dostaneme to, pretože. regulárne výrazy sú štandardne „nenásytné“. Chamtivosť môžete odstrániť pomocou modifikátora " U", Páči sa ti to:

#()#U

Modifikátory

Za regulárnymi výrazmi môžu nasledovať modifikátory: " #HereRegularExpressionBody#HereModifiers"Typy modifikátorov:

i Povolí režim bez rozlišovania malých a veľkých písmen, t.j. veľké a malé písmená vo výraze sa nelíšia.
m Označuje, že vyhľadávaný text by sa mal považovať za viacero riadkov. V predvolenom nastavení modul regulárneho výrazu zaobchádza s textom ako s jedným riadkom bez ohľadu na to, čo v skutočnosti je. Podľa toho metaznaky "^" a "$" označte začiatok a koniec celého textu. Ak je zadaný tento modifikátor, budú ukazovať na začiatok a koniec každého riadku textu.
s Predvolený metaznak je " . " nezahŕňa vo svojej definícii znak nového riadku. Zadanie tohto modifikátora toto obmedzenie odstráni.
U Odstraňuje chamtivosť regulárneho výrazu
u Umožňuje prácu s regulárnymi výrazmi Cyrilika na UTF-8 inak to nefunguje správne.

php funkcie na prácu s regulárnymi výrazmi

preg_replace

Hľadať a nahradiť:

preg_replace (zmiešaný $vzor , zmiešaný $náhrada , zmiešaný $predmet [, int $limit = -1 [, int &$počet ]]);

Každá hodnota môže byť reťazec alebo pole $predmet pole - vráti sa pole, inak reťazec

preg_split

Rozdelí reťazec podľa regulárneho výrazu:

preg_split(reťazec $vzor , reťazec $predmet [, int $limit = -1 [, int $príznaky = 0 ]]);

Vráti pole pozostávajúce z podreťazcov daného reťazca predmet, ktorý je rozdelený pozdĺž hraníc, ktoré zodpovedajú vzoru vzor.

Regulárne výrazy sú špeciálne vzory na vyhľadávanie podreťazca v texte. S ich pomocou môžete vyriešiť tieto problémy v jednom riadku: „skontrolujte, či reťazec obsahuje čísla“, „nájdite všetky e-mailové adresy v texte“, „nahradte niekoľko po sebe idúcich otáznikov jedným“.

Začnime jednou populárnou programátorskou múdrosťou:

Niektorí ľudia, keď čelia nejakému problému, si pomyslia: „Áno, som šikovný, vyriešim to regulárnymi výrazmi.“ Teraz majú dva problémy.

Príklady šablón

Začnime niekoľkými jednoduchými príkladmi. Prvý výraz na obrázku nižšie hľadá sekvenciu 3 písmen, kde prvé písmeno je „k“, druhé je akékoľvek ruské písmeno a tretie je „t“ bez ohľadu na malé a veľké písmená (napr. „mačka“ alebo „ CAT“ sa hodí k tomuto vzoru). Druhý výraz hľadá v texte čas vo formáte 12:34 .

Akýkoľvek výraz začína znakom oddeľovača (oddeľovač v angličtine). Zvyčajne sa používa ako symbol /, ale môžu sa použiť aj iné znaky, ktoré v regulárnych výrazoch nemajú špeciálny účel, ako napríklad ~ , # alebo @ . Ak sa vo výraze môže vyskytovať znak /, používajú sa alternatívne oddeľovače. Potom nasleduje šablóna reťazca, ktorý hľadáme, nasleduje druhý oddeľovač a na koniec môže ísť jedno alebo viac vlajkových písmen. Nastavujú ďalšie možnosti pri vyhľadávaní textu. Tu sú príklady vlajok:

  • i - hovorí, že vyhľadávanie by nemalo rozlišovať veľké a malé písmená (štandardne sa rozlišujú malé a veľké písmená)
  • u - hovorí, že výraz a hľadaný text používajú kódovanie utf-8, nielen latinské písmená. Bez neho nemusí vyhľadávanie ruských (a akýchkoľvek iných nelatinských) znakov fungovať správne, preto by ste si ho mali vždy nasadiť.

Samotná šablóna pozostáva z bežných znakov a špeciálnych vzorov. Nuž, napríklad písmeno „k“ v regulárnych výrazoch znamená samo seba, ale symboly znamenajú „na tomto mieste môže byť akékoľvek číslo od 0 do 5“. Tu je úplný zoznam špeciálnych znakov (v príručke php sa nazývajú metaznaky) a všetky ostatné znaky v regulárnom výraze sú bežné:

Nižšie analyzujeme význam každého z týchto znakov (a tiež vysvetlíme, prečo je písmeno „ё“ umiestnené oddelene v prvom výraze), ale zatiaľ sa pokúsime použiť naše regulárne výrazy na text a uvidíme, čo sa stane. PHP má špeciálnu funkciu preg_match($regexp, $text, $match) , ktorá berie ako vstup regulárny výraz, text a prázdne pole. Skontroluje, či text obsahuje podreťazec, ktorý sa zhoduje s daným vzorom, a vráti 0, ak nie, alebo 1, ak áno. A v odovzdanom poli sa prvá nájdená zhoda s regulárnym výrazom umiestni do prvku s indexom 0. Napíšme jednoduchý program, ktorý aplikuje regulárne výrazy na rôzne reťazce:

Teraz, keď sme videli príklad, poďme podrobnejšie preskúmať regulárne výrazy.

Zátvorky v regulárnych výrazoch

Zopakujme si, čo znamenajú jednotlivé typy zátvoriek:

  • Zložené zátvorky a(1,5) určujú počet opakovaní predchádzajúceho znaku - v tomto príklade výraz hľadá 1 až 5 po sebe idúcich písmen "a"
  • Hranaté zátvorky znamenajú "ktorýkoľvek z týchto znakov", v tomto prípade písmená a, b, c, x, y, z alebo číslo od 0 do 5. Vo vnútri hranatých zátvoriek sú iné špeciálne znaky ako | alebo * - označujú obyčajný znak. Ak je na začiatku v hranatých zátvorkách symbol ^, význam je obrátený: „akýkoľvek jeden znak okrem tých, ktoré sú uvedené“ – napríklad [^a-c] znamená „ľubovoľný jeden znak okrem a, b alebo c“ .
  • Zátvorky zoskupujú znaky a výrazy. Napríklad vo výraze abc+ sa znamienko plus vzťahuje len na písmeno c a tento výraz hľadá slová ako abc, abcc, abccc. A ak vložíte zátvorky a (bc) +, kvantifikátor plus už odkazuje na sekvenciu bc a výraz hľadá slová abc, abcbc, abcbcbc

Poznámka: Rozsahy znakov je možné špecifikovať v hranatých zátvorkách, ale nezabudnite, že ruské písmeno ё je oddelené od abecedy a na napísanie „akéhokoľvek ruského písmena“ musíte napísať [а-яё] .

bexleshi

Ak ste si pozreli iné tutoriály o regulárnych výrazoch, pravdepodobne ste si všimli, že spätné lomítko sa všade píše inak. Niekde píšu jedno spätné lomítko: \d , ale tu sa v príkladoch opakuje 2 krát: \\d . prečo?

Jazyk regulárnych výrazov vyžaduje, aby ste spätnú lomku napísali raz. Avšak v jednoduchých a dvojitých úvodzovkách v PHP má spätné lomítko tiež špeciálny význam: príručka o reťazcoch. Napríklad, ak napíšete $x = "\$"; potom to PHP vezme ako špeciálnu kombináciu a do reťazca vloží iba znak $ (a regulárny engine nebude vedieť o spätnej lomke pred ním). Ak chcete vložiť sekvenciu \$ do reťazca, musíme zdvojnásobiť spätnú lomku a napísať kód ako $x = "\\$"; .

Z tohto dôvodu sme v niektorých prípadoch (kde má sekvencia znakov v PHP špeciálny význam) povinní zdvojnásobiť spätnú lomku:

  • Ak chcete písať regulárnym výrazom \$ , napíšeme kód "\\$"
  • Ak chcete napísať \\ v regulárnom výraze, zdvojnásobíme každú spätnú lomku a napíšeme "\\\\"
  • Ak chcete zapísať spätnú lomku a číslo (\1) v regulárnom výraze, spätná lomka musí byť zdvojnásobená: "\\1"

V ostatných prípadoch jedna alebo dve spätné lomky poskytnú rovnaký výsledok: "\\d" a "\d" vložia do reťazca pár znakov \d - v prvom prípade sú 2 spätné lomky poradie na vloženie spätnej lomky , v druhom prípade nejde o žiadnu špeciálnu sekvenciu a znaky sa vložia tak, ako sú. Pomocou echo: echo "\$" môžete skontrolovať, aké znaky budú vložené do reťazca a čo uvidí modul regulárneho výrazu; . Áno, je to ťažké, ale čo sa dá robiť?

Špeciálne konštrukcie v regulárnych výrazoch

  • \d hľadá akúkoľvek jednu číslicu, \D - akýkoľvek jeden znak iný ako číslica
  • \w zodpovedá akémukoľvek jednotlivému písmenu (akejkoľvek abecede), číslici alebo podčiarkovníku _ . \W sa zhoduje s ľubovoľným znakom okrem písmena, čísla a podčiarkovníka.

Tiež existuje vhodná podmienka pre ukazovanie na hranicu slova: \b . Táto konštrukcia znamená, že na jednej strane by mal byť znak, ktorým je písmeno/číslo/podčiarkovník (\w), a na druhej strane nie. Napríklad v texte chceme nájsť slovo „mačka“. Ak napíšeme regulárny výraz /cat/ui , potom nájde poradie týchto písmen kdekoľvek – napríklad vo vnútri slova „beštia“. Toto sme zjavne nechceli. Ak k regulárnemu výrazu pridáme okrajovú podmienku slova: /\bcat\b/ui , tak sa teraz bude hľadať iba samostatné slovo „mačka“.

Manuálny

  • Syntax regulárnych výrazov v PHP, podrobný popis