LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Perl (22) - Regulární výrazy - přepínače

Jak použít v regulárních výrazech přepínače?

21.12.2005 06:00 | Jiří Václavík | Články autora | přečteno 23985×

Přepínače (volby) mění chování regulárního výrazu. Uvádějí se na konec regulárního výrazu (tedy za poslední lomítko, je-li uvozovacím znakem). Jejich počet není omezen. Lze je definovat globálně nebo, jak poznáme v příštím díle, lokálně.

Kompletní seznam přepínačů pro hledání a nahrazování je v tabulce:

PřepínačVýznam
evyhodnocuje náhradu jako výraz (jen u nahrazování)
gpamatuje si pozici, na které skončilo poslední vyhledávání
inezáleží na velikosti písmen
mmetaznaky ^ resp. $ jsou na začátku resp. konci všech řádků
opřekládá vzor jen jednou
smnožina značící se tečkou zahrnuje i znak nového řádku
xspeciální syntaxe regulárních výrazů s komentáři

S některými jsme se již setkali, s některými zatím ne. Nyní jejich použití komplexně shrneme.

Velikost písma

  print "MATCHED" if "Perl" =~ /perl/i#vyhovuje

Regulární výraz vrátí true. V řetězci se sice "perl" nikde nevyskytuje, ale protože s přepínačem i se nerozlišuje velikost písmen, vyhoví i "Perl".

Vícenásobné prohledávání

Uvedením přepínače g si Perl zapamatuje, na které pozici byl nalezen výskyt a příště pokračuje od ní. To se dá využít v testu cyklu. Používá se k vyhledávání nebo nahrazování všech výskytů (implicitně je hledán jen 1. výskyt).

  $retezec = "www.linuxsoft.cz";
  while ($retezec =~ /linux/g){
      $i++;
  }
  print "Počet výskytů slova linux v řetězci je $i\n";

Existuje i speciální varianta přepínače g a to gc. Jejím použitím zabráníte resetu hodnoty v případě nezdaru při porovnávání.

V seznamovém kontextu lze přepínač g užít, chceme-li získat seznam všech zapamatovaných řetězců nebo řetězců, které vyhověli vzoru.

  @slova = ($retezec =~ /\w+/g);

Komentáře v regulárních výrazech

Přepínač x aktivuje speciální zápis regulárních výrazů. Čitelnost výrazu přitom rapidně roste. Jsou totiž ignorovány mezery a znaky nového řádku v regulárních výrazech. To mimo jiné umožňuje další příjemnou věc, kterou je možnost využití komentářů. Pozor si dejte jen na lomítko, popř. jiný zvolený uvozovací znak v komentáři.

Připomeňme si vzor, kterému vyhoví dvanáctihodinový čas:

  /^((0\d)|(1[0-2]))[:\.][0-5]\d[:\.][0-5]\d[ ]?[pa]m$/i;

Na 1. pohled asi těžko poznáte, co by měl takový výraz vyjadřovat. S přepínačem x to bude za pár sekund jasné:

  $cas = "12:22:11 am";
  print "MATCHED\n" if $cas =~ /
      #regulární výraz pro formát dvanáctihodinového času
      ^
      ((0\d)|(1[0-2]))   #HODINA - číslo mezi 00 a 12
      [:\.]              #oddělovač hodin a minut
      [0-5]\d            #MINUTA - číslo mezi 00 a 59
      [:\.]              #oddělovač minut a sekund
      [0-5]\d            #SEKUNDA - číslo mezi 00 a 59
      [ ]?               #nepovinná mezera
      [pa]m              #určení doby - dopoledne nebo odpoledne; přepínač i zajišťuje, že nezáleží na velikosti písmen
      $
      /xi;

Toto, jak se dozvíte příštím díle, není jediný způsob, jak vkládat do regulárních výrazů komentáře.

Jednorázová kompilace regulárního výrazu

Zejména pro urychlení programu se používá přepínač o. Regulární výraz v nějakém cyklu s přepínačem o je přeložen vždy pouze jednou a tento překlad je pak použit v každé iteraci. Tedy bez ohledu na hodnoty proměnných, které, jak víme, lze do vzorů také zakomponovat. Proměnné, uvedené v regulárním výrazu, se mohou měnit, a pak se tedy mění i samotný regulární výraz. Přepínač o tomu z výše uvedeného důvodu zamezuje. Každou iteraci je použit regulární výraz, který vznikl kompilací v první iteraci.

Ukládání regulárních výrazů

S přepínačem o souvisí jiná věc. Existuje možnost předkompilace - použití konstrukce qr//. Pokud takový regulární výraz přiřadíte do proměnné, lze ji používat místo onoho regulárního výrazu.

  $reg = qr/\d\d\d/;
  print "MATCHED" if "12" =~ $reg;   #nevyhovuje
  print "MATCHED" if "123" =~ $reg#vyhovuje
  print "MATCHED" if "77a" =~ $reg;  #nevyhovuje
  print "MATCHED" if "7744" =~ $reg; #vyhovuje

Je též možné takový regulární výraz v proměnné zařadit do jiného regulárního výrazu.

  print "MATCHED" if "7744" =~ /^$reg$/;   #nevyhovuje
  print "MATCHED" if "7744" =~ /^\d$reg$/; #vyhovuje

Zkusíte-li proměnnou, ve které je regulární výraz uložen, vytisknout, bude vypadat výstup v našem případě takto: (?-xism:\d\d\d).

Náhrada jako výraz

S touto vlastností můžete plodit divy. U nahrazování jsme psali náhradu jako text. Uvedení přepínače e umožní napsat náhradu jako výraz (má to mnoho společného s eval). To by nebylo nic objevného, kdyby v ní nešlo používat zapamatované proměnné. Právě v tom tkví kouzlo.

Uvedeme si 2 příklady. Přepínač e se dobře vysvětluje pomocí funkce reverse. Převrátíme pořadí písmen ve všech slovech řetězce:

  $retezec = "prisel jsem - videl jsem - zvitezil jsem";
  $retezec =~ s/(\w+)/reverse $1/ge;
  print $retezec; lesirp mesj - lediv mesj - lizetivz mesj

V proměnné $1 máme uložena postupně všechna (je použit také přepínač g) slova a na každé je aplikována funkce reverse.

Pojďme dál a zkusme něco složitějšího. V řetězci, který budeme zpracovávat, se vyskytují ceny v amerických dolarech. Upravíme tento řetězec regulárním výrazem tak, abychom dolary nahradili českými korunami a to se vším všudy. Musíme tedy přepočítat částku v dolarech na částku v korunách a zaměnit symbol měny. Navíc je nutné ošetřit případné desetinné ceny.

  $usd2czk = 24.133; #kurz k dolaru z 19.12.2005
  $retezec = "Cena: 20.5\$";
  $retezec =~ s/((\d+(.\d+)?)(\$|USD))/$2*$usd2czk.CZK/ge;
  print $retezec;

Předpokládali jsme, že symbol měny se píše vždy za hodnotu a mezi hodnotou a symbolem není mezera. Tisknut je řetězec "Cena: 494.7265CZK". Je zde ponecháno zbytečně mnoho desetinných míst. Pomocí funkce sprintf je lze oříznout tak, aby byly vytištěny vždy právě dvě, případně doplněné nulami.

  $retezec =~ s/((\d+(.\d+)?)(\$|USD))/sprintf("%.2f", $2*$usd2czk).CZK/ge;

Pokud si zkusíte nahradit vstupující text za nějaký složitější, kde se vyskytuje cena v dolarech vícekrát, jsou nahrazeny všechny. Zajímavé by také mohlo být získávání aktuálního kurzu za běhu.

Přepínač e má ještě jednu zajímavou vlastnost. Lze ho uvést pro 1 regulární výraz vícekrát. Ilustrujme si to na této ukázce.

  $xxx = "XXX";
  $_ = "***\$xxx***";
  s/(\$\w+)/$1/ee;
  print;

Počáteční stav s 2 přepínači e:

  s/(\$\w+)/$1/ee;

V 1. kroku je jedno e spotřebováno na nahrazení proměnné $1 svým obsahem, tedy řetězcem '$xxx'.

  s/(\$\w+)/$xxx/e;

Zbývá nám ještě poslední e, které vyhodnotí výraz $xxx - tedy nahradí proměnnou $xxx jejím obsahem.

  s/(\$\w+)/XXX/;

Příště budeme v regulárních výrazech pokračovat a podíváme se na zoubek rozšířeným vzorům.

Verze pro tisk

pridej.cz

 

DISKUZE

Nejsou žádné diskuzní příspěvky u dané položky.



Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

16.7.2018 1:05 /František Kučera

Červencový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 7. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát bude přednáška na téma: automatizační nástroj Ansible, kterou si připravil Martin Vicián.


Přidat komentář

18.6.2018 0:43 /František Kučera
Červnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 21. 6. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát na téma: F-Droid, aneb svobodný software do vašeho mobilu. Kromě toho budou k vidění i vývojové desky HiFive1 se svobodným/otevřeným čipem RISC-V.
Přidat komentář

23.5.2018 20:55 /Ondřej Čečák
Od pátku 25.5. proběhne na Fakultě informačních technologií ČVUT v Praze openSUSE Conference. Můžete se těšit na spostu zajímavých přednášek, workshopů a také na Release Party nového openSUSE leap 15.0. V na stejném místě proběhne v sobotu 26.5. i seminář o bezpečnosti CryptoFest.
Přidat komentář

20.5.2018 17:45 /Redakce Linuxsoft.cz
Ve čtvrtek 31. května 2018 připravuje webový magazín BusinessIT ve spolupráci s Best Online Média s.r.o. pátý ročník odborné konference Firemní informační systémy 2018. Akce proběhne v kongresovém centru Vavruška (palác Charitas), Karlovo náměstí 5, Praha 2 (u metra Karlovo náměstí) od 9:00 hod. dopoledne do cca 15 hod. odpoledne. Konference je zaměřena na efektivní využití firemních informačních systémů a na to, jak plně využít jejich potenciál. Podrobnější informace na webových stránkách konfrence.
Přidat komentář

14.5.2018 7:28 /František Kučera
Květnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 17. 5. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát na téma: Audio – zvuk v GNU/Linuxu.
Přidat komentář

7.5.2018 16:20 /František Kučera
Na stránkách spolku OpenAlt vyšla fotoreportáž Pražské srazy 2017 dokumentující srazy za uplynulý rok. Květnový pražský sraz na téma audio se bude konat 17. 5. 2018 (místo a čas ještě upřesníme).
Přidat komentář

17.4.2018 0:46 /František Kučera
Dubnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 4. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tématem tohoto srazu bude OpenStreetMap (OSM) aneb svobodné mapy.
Přidat komentář

16.3.2018 22:01 /František Kučera
Kulatý OpenAlt sraz v Praze oslavíme klasicky: u limonády a piva! Přijďte si posedět, dát si dobré jídlo a vybrat z mnoha piv do restaurace Kulový blesk, který najdete v centru Prahy nedaleko metra I. P. Pavlova na adrese Sokolská 13, Praha 2. Sraz se koná ve čtvrtek 22. března a začínáme v 18:00. Heslo: OpenAlt. Vezměte s sebou svoje hračky! Uvítáme, když si s sebou na sraz vezmete svoje oblíbené hračky. Jestli máte nějaký drobný projekt postavený na Arduinu, nějakou zajímavou elektronickou součástku, či třeba i pěkný úlovek z crowdfundingové akce, neváhejte. Oslníte ostatní a o zábavu bude postaráno.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

20.2.2018 18:48 / Ivan Majer
portal

20.2.2018 15:57 / Jan Havel
Jak využíváte služby cloudu v podnikání?

16.1.2018 1:08 / Ivan Pittner
verejna ip od o2 ubuntu

15.1.2018 17:26 / Mira Harvalik
Re: Jak udělat HTML/Javascript swiping gallery do mobilu?

30.12.2017 20:16 / Michal Knoll
odmocnina

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2018) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze