Porovnávání řetězců


Jednou z největších výhod Perlu (možná i největší) jsou výkonné prostředky pro manipulaci se řetězci. Základem jsou regulární výrazy (RE), které jsou použitelné mnoha dalšími utilitami UNIXu.


Regulární výrazy (RE)

Regulární výrazy jsou uzavřeny do lomítek. Porovnání s regulárním výrazem se provádí pomocí operátoru =~.
Příklad: Následující výraz je pravdivý, pokud se v proměnné $sentence vyskytuje řetězec velka.
$sentence =~ /velka/
RE jsou case sensitive (rozlišuje se mezi malými a velkými písmeny). Pokud tedy proměnná $sentence odsahuje řetězec
$sentence = "Velka rezata liska";
potom porovnání $sentence =~ /velka/ je nepravdivé.

Operátor !~ je používán k testování nerovnosti. Pokud tedy proměnná $sentence odsahuje řetězec

$sentence = "Velka rezata liska";
je výraz $sentence !~ /velka/ pravdivý, protože řetězec velka se nevyskytuje v proměnné $sentence.


Speciální proměnná $_

Regulární výraz můžeme použít v podmíněném příkazu
if ($sentence =~ /under/)
{
	print "We're talking about rugby\n";
}
Blok příkazů bude vypisovat zprávu, pokud bude obsah proměnné $sentence např.
$sentence = "Up and under";
$sentence = "Best winkles in Sunderland";
Postup je jednodušší, pokud přiřadíme řetězec proměnné se jménem $_. Proměnná $_ je skalární proměnná. Pokud tak učiníme, nemusíme používat srovnávací operátory a můžeme jednodušše zapsat
if (/under/)
{
	print "We're talking about rugby\n";
}
Proměnná $_ je implicitní pro mnohé operace Perlu a používá se velice často.


Více o RE

V RE se používá mnoho speciálních znaků. Právě tyto speciální znaky dělají z RE silné prostředky, ale také způsobují, že RE vypadají na pohled komplikovaně.

RE je vhodné začít používat postupně, jejich vytváření je často určitým druhem umění.

Uvedeme některé speciální znaky používané v RE a jejich význam

.	# libovolný znak, kromě znaku pro nový řádek
^	# začátek řádky nebo řetězce
$	# konec řádky nebo řetězce
*	# žádný nebo několik výskytů předchozího znaku
+	# jeden nebo několik výskytů předchozího znaku
?	# žádný nebo jeden výskyt posledního znaku
a příklady použití porovnání. Připomeňme, že výrazy RE musí být uzavřeny do lomítek (/.../).
t.e	# výraz představuje řetězec začínající t následované čímkoli (alespoň 
          jedním znakem) a končící písmenem e
	# Vyhovuje např.:       the
	#                       tre
	#                       tle
	# ale nevyhovuje        te
	#                       tale
^f	# f na začátku řádky
^ftp	# ftp na začátku řádky
e$	# e na konci řádky
tle$	# tle na konci řádky
und*	# un následované žádným nebo více znaky d
	# vyhovuje  např.      un
	#                      und
	#                      undd
	#                      unddd (atd)
.*	# libovolný řetězec bez znaků nový řádek. Protože
	#  . vyhovuje libovolnému znaku kromě nového řádku a
	# * znamená žádný nebo více výskytů posledního znaku.
^$	# řádek s prázdným obsahem.

Existují další možnosti.
Pro porovnání se skupinou znaků se používají hranaté závorky. Porovnání se provádí na libovolný znak uvnitř závorek. Pomlčka (-) uvnitř hranatých závorek označuje znaky mezi uvedenými znaky a znak ^ na začátku závorky znamená negaci:

[qjk]		# q nebo j nebo k
[^qjk]		# ani j ani g ani k
[a-z]		# cokoli od a do z včetně znaků a a z
[^a-z]		# nikoli malá písmena
[a-zA-Z]	# libovolné písmeno
[a-z]+		# libovolný neprázdný řetězec z malých písmen
V tomto bodě můžete přeskočit na příklady, zbytek kapitoly je uvedený jako referční seznam.

Vertikální čára | znamená "or" a kulaté závorky (...) je možné použít k seskupování:

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

Některé speciální znaky:

\n		# nový řádek
\t		# tabelátor
\w		# libovolný alfanumerický znak,
		# \w je ekvivalentní s [a-zA-Z0-9_]
\W		# libovolný nealfanumerický znak,
		# \W je ekvivalentní s [^a-zA-Z0-9_]
\d		# libovolná číslice, tj. [0-9]
\D		# znak jiný než číslice, tj. [^0-9]
\s		# znak pro vložené mezery, tj. mezera,
		# tab, nový řádek, atd.
\S		# nemezerový znak
\b		# hranice slova, tento znak nelze použít uvnitř []
\B		# na uvedeném místě není hranice slova

Znaky jako $, |, [, ), \, / a mají v RE zvláštní význam. Pokud chcete porovnávat na výskyt některého z těchto znaků, musíte před nimi uvést zpětné lomítko. Tj:

\|		# svislá čára
\[		# úvodní hranatá závorka
\)		# koncová závorka
\*		# hvězdička
\^		# stříška
\/		# lomítko
\\		# zpětné lomítko
atd.


Příklady RE

Jak bylo uvedeno výše ja lepší začít používat RE postupně a pomalu. Uveďme několik příkladů. připomeňme, že při použití ve srovnání musí být RE uzavřeny v lomítkách /.../.
[01]		#  "0" nebo "1"
\/0		#  dělení nulou "/0"
\/ 0		#  dělení nulou s mezerou "/ 0"
\/\s0		# dělení nulou s mezerovým znakem
		# "/ 0" kde mezerový znak může být tabelátor atd.
\/ *0		# dělení nulou s možnými mezerami
		#  "/0" nebo "/ 0" nebo "/  0" atd.
\/\s*0		# dělení nulou s možnými mezerovými znaky
		# 
\/\s*0\.0*	# jako předchozí výraz, ale s desetinou tečkou a možnými    
		# nulami za tečkou. 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 proměnné $_ je 
{                         # uložena e-mail adresa
  $uzivatel=$1;
  $domena=$2;
} 


Cvičení

Příklad 4. Předchozí verze programu počítala pouze neprázdné řádky. Pozměňte program tak, aby počítal pouze řádky, které obsahují V každém případě má program opisovat všechny řádky, ale počítat musí jen ty, které obsahují uvedený znak nebo řetězec. Zkuste použít proměnnou $_ a tím zjednodušit zápis. Rěšení.


Další kapitola | Předchozí kapitola kapitola | Obsah