_  _   ,_
/^\/^\-/ @D
~(________/ PERL.LT
|L |L
L L
Straipsniai  Funkcijos 
Straipsniai/Apie įpraiškas
Jeigu perskaitėte straipsnį apie įprastines išraiškas, tai gal būt jau ir suprantate pagrindines
išraiškų idėjas. Pabandysiu duoti išsamų pavyzdį, kuris aprašys kaip galima įprastinių išraiškų
pagalba aprašyti skaičius.

Pirmiausia sudarant įprastinę išraišką reikia nuspręsti ką mes norime į ją įtraukti ir ko ne.
Mūsų atveju mes norime kad įprastinė išraiška atitiktų sveikuosius ir realiuosius skaičius ir
neatitiktų bet kokią kitą simbolių eilutę. 

Antra užduotis sudarant įprastinę išraišką yra suskaidyti uždavinį į keletą mažesnių, kad juos
lengviau būtų galima paversti įprastine išraiška.

Paprasčiausia yra su sveikais skaičiais. Jie sudaromi iš skaitmenų ir prieš juos gali būti
teigiamas arba neigiamas ženklas (nors gali ir nebūti). Skaitmenis galime aprašyti kaip \d+,
o ženklą kaip [+-], tad sveikų skaičių įprastinė išraiška yra:

	/[+-]?\d+/;	# atitinka sveikus skaičius

Realusis skaičius sudaromas iš ženklo, sveikosios dalies, taško, trupmeninės dalies ir eksponentės.
Nebūtinai turi egzistuoti visos šios sudedamosios dalys, todėl reikia aprašyti visas galimybes.
Štai teisingų realiųjų skaičių pavyzdžiai: "123.", "0.345", ".34", "-1e6", "25.4E-72". Kaip ir su
sveikaisiais skaičiais, žeklas gali būti, gali ir nebūti todėl tai atitinka "[+-]?". Kaip matome,
jei nėra eksponentės, realieji skaičiai turi turėti tašką, nes priešingu atveju jie būtų paprasčiausi
sveikieji skaičiai. Nors ir galbūt norėtume tai aprašyti išraiška "\d*\.\d*", bet tai nebūtų teisinga,
nes tai kartu atitiktų ir vien tik tašką, kuris nėra skaičius. Taigi trys realiųjų skaičių tipai be
eksponentės yra šie:

	/[+-]?\d+\./;		# "1.", "321." ir pan.
	/[+-]?\.\d+/;		# ".1", ".234" ir pan.
	/[+-]?\d+\.\d+/;	# "1.0", "30.56" ir pan.

Visą tai galima perrašyti viena šraiška naudojant alternatyvas:

	/[+-]?(\d+\.\d+|\d+\.|\.\d+)/;	# realusis skaičius be eksponentės

Šiose alternatyvose svarbu kad "\d+\.\d+" eitų prieš "\d+\.", nes jei "\d+\." būtų pirmas, tai
įprastinė išraiška atitiktų sveikąją dalį ir visai ignoruotų trupmeninę dalį, net jei ji ir egzistuotų. 

Dabar tarkime kad turime sveikąjį skaičių su eksponente. Svarbu pažymėti, kad prieš eksponentę gali
būti tiek sveiki, tiek realieji skaičiai. Taigi, eksponentę galima visiškai atskirti nuo mantisės.
Štai pseudokodo pavyzdys:

	/^(neprivalomas ženklas)(sveikas skaičius | realusis skaičius)(neprivaloma eksponentė)$/;

Eksponentė yra 'e' arba 'E' bei po jos einanti sveikasis skaičius, tad įprastinė išraiška atitinkanti
eksponentę yra:

	/[eE][+-]?\d+/;	# eksponentė

Visa tai sudėdami į vieną išraišką gauname įprastinę išraišką, atitinkančią realiuosius skaičius:

	/^[+-]?(\d+\.\d+|\d+\.|\.\d+|\d+)([eE][+-]?\d+)?$/;	# Na štai

Ilgomis įprastinėmis išraiškomis gal ir sužavėsite savo draugus, bet jas sunku perskaityti. Tokiais
atvejais labai naudingas sudėtingų įprastinių išraiškų modifikatorus /x.Jis leidžia į įprastines
išraiškas įterpti komentarus bei gražiai ją suformuoti. Štai kaip mūsų realiųjų skaičių išraiška
atrodo perrašyta us /x modifikatoriumi:

	/^
		[+-]?			# pirma, nebūtinas ženklas
		(			# tada mantisės:
			\d+\.\d+	# mantisės forma a.b
			|\d+\.		# mantisės forma a.
			|\.\d+		# mantisės forma .b
			|\d+ 		# sveiko skaičiaus forma a
		)
		([eE][+-]?\d+)?		# galų gale, nebūtina eksponentė
	$/x;

Tarkime, kad tarp ženklo ir skaičiaus gali būti ir tarpų. Prieš tarų ženklą reikia padėti '\',
nes naudojamas /x modifikatorius:

	/^
		[+-]?\ *		# pirma, nebūtinas ženklas ir nebūtinas ženklas
		(			# tada mantisės:
			\d+\.\d+	# mantisės forma a.b
			|\d+\.		# mantisės forma a.
			|\.\d+		# mantisės forma .b
			|\d+ 		# sveiko skaičiaus forma a
		)
		([eE][+-]?\d+)?		# galų gale, nebūtina eksponentė
	$/x;

Taip pasirašius įprastinę išraišką lengva pastebėti, kad 1, 2 ir 4 alternatyvos prasideda "\d+",
tad viską galime suprastinti:

	/^
		[+-]?\ *		# pirma, nebūtinas ženklas ir nebūtinas ženklas
		(			# tada mantisės:
			\d+		# pradedam su a ...
			(
				\.\d*	# mantisės forma a.b arba a.
			)?		# ? aprašo ir sveikus skaičius a
			|\.\d+		# mantisės forma .b
		)
		([eE][+-]?\d+)?		# galų gale, nebūtina eksponentė
	$/x;

Arba tą patį galima perrašyti kompaktiškoje formoje:

	/^[+-]?\ *(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/;

Tai mūsų galutinė įprastinė išraiška. Mes ją parašėme:
	* detaliai aprašydami užduotį,
	* suskaidydami problemą į dalis,
	* išversdami mažas dalis į įprastnes išraiškas,
	* sujungdami šias dalis,
	* optimizuodami įprastinę išraišką.

Tai įprastiniai žingsniai rašant kompiuterinę programą, ir nieko čia nuostabaus, nes įprastinės
išraiškos ir yra tarsi nedidelės programos. 
algirdas@perl.lt 2005.04.11 - $dabar