Porovnavani retezcu


Jednou z nejvetsich vyhod Perlu (mozna i nejvetsi) jsou vykonne prostredky pro manipulaci se retezci. Zakladem jsou regularni vyrazy (RE), ktere jsou pouzitelne mnoha dalsimi utilitami UNIXu.


Regularni vyrazy (RE)

Regularni vyrazy jsou uzavreny do lomitek. Porovnani s regularnim vyrazem se provadi pomoci operatoru =~.
Priklad: Nasledujici vyraz je pravdivy, pokud se v promenne $sentence vyskytuje retezec velka.
$sentence =~ /velka/
RE jsou case sensitive (rozlisuje se mezi malymi a velkymi pismeny). Pokud tedy promenna $sentence odsahuje retezec
$sentence = "Velka rezata liska";
potom porovnani $sentence =~ /velka/ je nepravdive.

Operator !~ je pouzivan k testovani nerovnosti. Pokud tedy promenna $sentence odsahuje retezec

$sentence = "Velka rezata liska";
je vyraz $sentence !~ /velka/ pravdivy, protoze retezec velka se nevyskytuje v promenne $sentence.


Specialni promenna $_

Regularni vyraz muzeme pouzit v podminenem prikazu
if ($sentence =~ /under/)
{
	print "We're talking about rugby\n";
}
Blok prikazu bude vypisovat zpravu, pokud bude obsah promenne $sentence napr.
$sentence = "Up and under";
$sentence = "Best winkles in Sunderland";
Postup je jednodussi, pokud priradime retezec promenne se jmenem $_. Promenna $_ je skalarni promenna. Pokud tak ucinime, nemusime pouzivat srovnavaci operatory a muzeme jednodusse zapsat
if (/under/)
{
	print "We're talking about rugby\n";
}
Promenna $_ je implicitni pro mnohe operace Perlu a pouziva se velice casto.


Vice o RE

V RE se pouziva mnoho specialnich znaku. Prave tyto specialni znaky delaji z RE silne prostredky, ale take zpusobuji, ze RE vypadaji na pohled komplikovane.

RE je vhodne zacit pouzivat postupne, jejich vytvareni je casto urcitym druhem umeni.

Uvedeme nektere specialni znaky pouzivane v RE a jejich vyznam

.	# libovolny znak, krome znaku pro novy radek
^	# zacatek radky nebo retezce
$	# konec radky nebo retezce
*	# zadny nebo nekolik vyskytu predchoziho znaku
+	# jeden nebo nekolik vyskytu predchoziho znaku
?	# zadny nebo jeden vyskyt posledniho znaku
a priklady pouziti porovnani. Pripomenme, ze vyrazy RE musi byt uzavreny do lomitek (/.../).
t.e	# vyraz predstavuje retezec zacinajici t nasledovane cimkoli (alespon 
          jednim znakem) a koncici pismenem e
	# Vyhovuje napr.:       the
	#                       tre
	#                       tle
	# ale nevyhovuje        te
	#                       tale
^f	# f na zacatku radky
^ftp	# ftp na zacatku radky
e$	# e na konci radky
tle$	# tle na konci radky
und*	# un nasledovane zadnym nebo vice znaky d
	# vyhovuje  napr.      un
	#                      und
	#                      undd
	#                      unddd (atd)
.*	# libovolny retezec bez znaku novy radek. Protoze
	#  . vyhovuje libovolnemu znaku krome noveho radku a
	# * znamena zadny nebo vice vyskytu posledniho znaku.
^$	# radek s prazdnym obsahem.

Existuji dalsi moznosti.
Pro porovnani se skupinou znaku se pouzivaji hranate zavorky. Porovnani se provadi na libovolny znak uvnitr zavorek. Pomlcka (-) uvnitr hranatych zavorek oznacuje znaky mezi uvedenymi znaky a znak ^ na zacatku zavorky znamena negaci:

[qjk]		# q nebo j nebo k
[^qjk]		# ani j ani g ani k
[a-z]		# cokoli od a do z vcetne znaku a a z
[^a-z]		# nikoli mala pismena
[a-zA-Z]	# libovolne pismeno
[a-z]+		# libovolny neprazdny retezec z malych pismen
V tomto bode muzete preskocit na priklady, zbytek kapitoly je uvedeny jako refercni seznam.

Vertikalni cara | znamena "or" a kulate zavorky (...) je mozne pouzit k seskupovani:

nanuk|zmrzlina	# nanuk nebo zmrzlina
(m|d)rak	# mrak nebo drak
(da)+		# da nebo dada nebo dadada nebo ..

Nektere specialni znaky:

\n		# novy radek
\t		# tabelator
\w		# libovolny alfanumericky znak,
		# \w je ekvivalentni s [a-zA-Z0-9_]
\W		# libovolny nealfanumericky znak,
		# \W je ekvivalentni s [^a-zA-Z0-9_]
\d		# libovolna cislice, tj. [0-9]
\D		# znak jiny nez cislice, tj. [^0-9]
\s		# znak pro vlozene mezery, tj. mezera,
		# tab, novy radek, atd.
\S		# nemezerovy znak
\b		# hranice slova, tento znak nelze pouzit uvnitr []
\B		# na uvedenem miste neni hranice slova

Znaky jako $, |, [, ), \, / a maji v RE zvlastni vyznam. Pokud chcete porovnavat na vyskyt nektereho z techto znaku, musite pred nimi uvest zpetne lomitko. Tj:

\|		# svisla cara
\[		# uvodni hranata zavorka
\)		# koncova zavorka
\*		# hvezdicka
\^		# striska
\/		# lomitko
\\		# zpetne lomitko
atd.


Priklady RE

Jak bylo uvedeno vyse ja lepsi zacit pouzivat RE postupne a pomalu. Uvedme nekolik prikladu. pripomenme, ze pri pouziti ve srovnani musi byt RE uzavreny v lomitkach /.../.
[01]		#  "0" nebo "1"
\/0		#  deleni nulou "/0"
\/ 0		#  deleni nulou s mezerou "/ 0"
\/\s0		# deleni nulou s mezerovym znakem
		# "/ 0" kde mezerovy znak muze byt tabelator atd.
\/ *0		# deleni nulou s moznymi mezerami
		#  "/0" nebo "/ 0" nebo "/  0" atd.
\/\s*0		# deleni nulou s moznymi mezerovymi znaky
		# 
\/\s*0\.0*	# jako predchozi vyraz, ale s desetinou teckou a moznymi    
		# nulami za teckou. Vyhovuje
		# "/0." a "/0.0" a "/0.00" atd a
		# "/ 0." a "/  0.0" a "/   0.00" atd.

if (/(\w*)@([a-z\.]+)/)   # kontrola, zda v promenne $_ je 
{                         # ulozena e-mail adresa
  $uzivatel=$1;
  $domena=$2;
} 


Cviceni

Priklad 4. Predchozi verze programu pocitala pouze neprazdne radky. Pozmente program tak, aby pocital pouze radky, ktere obsahuji V kazdem pripade ma program opisovat vsechny radky, ale pocitat musi jen ty, ktere obsahuji uvedeny znak nebo retezec. Zkuste pouzit promennou $_ a tim zjednodusit zapis. Reseni.


Dalsi kapitola | Predchozi kapitola kapitola | Obsah