Vous êtes sur la page 1sur 18

============== Perl Crash Course:============

MA Interactive Media
Published January 2010
=============================================

Lastsemesterwelookedbrieflyattoolswe
couldusefromthecommandline.Perlgives
ustheabilitytogluethosecommands
together.
YoushouldspendhalfhourlearningVIM

Tutorial
Majorityofthecontentsofthistutorialsectionwerewrittenby
NikSilver,attheSchoolofComputerStudies,Universityof
Leeds,UK.Assumingnoworkingknowledgeofanyprogramming
language,wewillnowtrytoseewhatPerlprogramslooklike.

FirstStep
EversinceKernighanandRitchiecameoutwithCprogramming
language,peoplehavestartedlearningalmostanyprogramming
languagewiththeobligatory"HelloWorld"program.

HelloWorld!
Hereisthebasicperlprogramthatwe'llusetogetstarted.

#!/usr/bin/perl
#
#printsagreeting.
#
print'Helloworld.';#Printamessage

Comments
AcommonPerlpitfallistowritecrypticcode.Inthatcontext,

Perldoprovideforcomments,albeitnotveryflexible.Perl
treatsanythingfromahash#totheendoflineasacomment.
Blockcommentsarenotpossible.So,ifyouwanttohaveablock
ofcomments,youmustensurethateachlinestartswith#.

Statements
EverythingotherthancommentsarePerlstatements,whichmustend
withasemicolon,likethelastlineabove.
APerlstatementalwaysendswithasemicolon.

2.2RunningPerl
perlhello.pl

Ifsomethinggoeswrongthenyoumaygeterrormessages,oryou
maygetnothing.Youcanalwaysruntheprogramwithwarnings
usingthecommand
perlwprogname

attheprompt.Thiswilldisplaywarningsandother(hopefully)
helpfulmessagesbeforeittriestoexecutetheprogram.

2.3Scalars
Perlsupports3basictypesofvariables,viz.,scalars,listsand
hashes.Wewillexploreeachoftheselittlemore.
ThemostbasickindofvariableinPerlisthescalarvariable.
Scalarvariablesholdbothstringsandnumbers,andareremarkable
inthatstringsandnumbersarecompletelyinterchangeable.For
example,thestatement
$age=27;

setsthescalarvariable$ageto27,butyoucanalsoassigna
stringtoexactlythesamevariable:
$age='TwentySeven';

Perlalsoacceptsnumbersasstrings,likethis:
$priority='9';
$default='0009';

Ingeneralvariablenamesconsistsofnumbers,lettersand
underscores,buttheyshouldnotstartwithanumberandthe
variable$_isspecial,aswe'llseelater.Also,Perliscase
sensitive,so$aand$AareVERYdifferent.

OperationsandAssignment
Perlusesalltheusualarithmeticoperators:
$a=1+2;#Add1and2andstorein$a
$a=34;#Subtract4from3andstorein$a
$a=5*6;#Multiply5and6
$a=7/8;#Divide7by8togive0.875
$a=9**10;#Ninetothepowerof10
$a=5%2;#Remainderof5dividedby2
++$a;#Increment$aandthenreturnit
$a++;#Return$aandthenincrementit
$a;#Decrement$aandthenreturnit
$a;#Return$aandthendecrementit

andforstringsPerlhasthefollowingamongothers:
$a=$b.$c;#Concatenate$band$c
$a=$bx$c;#$brepeated$ctimes

ToassignvaluesPerlincludes
$a=$b;#Assign$bto$a
$a+=$b;#Add$bto$a
$a=$b;#Subtract$bfrom$a
$a.=$b;#Append$bonto$a

NotethatwhenPerlassignsavaluewith$a=$bitmakesacopy
of$bandthenassignsthatto$a.Thereforethenexttimeyou
change$bitwillnotalter$a.

Interpolation
Thefollowingcodeprintsbathandhouseusingconcatenation:
$a='bath';
$b='house';
print$a.'and'.$b;

Itwouldbenicertoincludeonlyonestringinthefinalprint
statement,buttheline
print'$aand$b';

printsliterally$aand$bwhichisn'tveryhelpful.Insteadwe
canusethedoublequotesinplaceofthesinglequotes:
print"$aand$b";

Thedoublequotesforceinterpolationofanycodes,including
interpretingvariables.Thisisamuchnicerthanouroriginal
statement.Othercodesthatareinterpolatedincludespecial
characterssuchasnewlineandtab.Thecode\nisanewlineand
\tisatab.

Exercise
ThisexerciseistorewritetheHelloworldprogramsothat(a)
thestringisassignedtoavariableand(b)thisvariableisthen

printedwithanewlinecharacter.Usethedoublequotesanddon't
usetheconcatenationoperator.

Lists(Arrays)
Aslightlymoreinterestingkindofvariableisthelistvariable
whichisanarrayofscalars(i.e.numbersandstrings).Fromnow
on,wewillusethetermslistandarrayinterchangeably.
Arrayvariableshavethesameformatasscalarvariablesexcept
thattheyareprefixedbyan@symbol.Thestatement
@computer=("algebra","money","mechanisation");
@poor=("crime","cold");

assignsathreeelementlisttothearrayvariable@computeranda
twoelementlisttothearrayvariable@poor.
Thearrayisaccessedbyusingindicesstartingfrom0,andsquare
bracketsareusedtospecifytheindex.Theexpression
$computer[2]

returnsmechanisation.Noticethatthe@haschangedtoa$
becausemechanisationisascalar.

Arrayassignments
AsinallofPerl,thesameexpressioninadifferentcontextcan
produceadifferentresult.Thefirstassignmentbelowexplodes
the@poorvariablesothatitisequivalenttothesecond
assignment.
@morepoor=("badschool",@poor,"badhealth");

Thisshouldsuggestawayofaddingelementstoanarray.Aneater
wayofaddingelementsistousethestatement
push(@poor,"badhealth");

whichpushesbadhealthontotheendofthearray@poor.Topush
twoormoreitemsontothearrayuseoneofthefollowingforms:
push(@poor,"badhealth","badschool");
push(@poor,("badhealth","badschool"));
push(@poor,@morepoor);

Thepushfunctionreturnsthelengthofthenewlist.Sodoes
$#poor;
Toremovethelastitemfromalistandreturnitusethepop
function.Fromouroriginallistthepopfunctionreturnseelsand
@foodnowhastwoelements:
$cost=pop(@poor);#Now$cost="cold"

Itisalsopossibletoassignanarraytoascalarvariable.As
usualcontextisimportant.Theline
$f=@poor;

assignsthelengthof@food,but
$f="@poor";

turnsthelistintoastringwithaspacebetweeneachelement.
Thisspacecanbereplacedbyanyotherstringbychangingthe
valueofthespecial$"variable.
Arrayscanalsobeusedtomakemultipleassignmentstoscalar
variables:
($a,$b)=($c,$d);#Sameas$a=$c;$b=$d;
($a,$b)=@poor;#$aand$barethefirsttwo
#itemsof@food.
($a,@somepoor)=@poor;#$aisthefirstitemof@poor
#@somepoorisalistofthe
#others.
(@somepoor,$a)=@poor;#@somepooris@poorand
#$aisundefined.

Thelastassignmentoccursbecausearraysaregreedy,and
@somepoorwillswallowupasmuchof@poorasitcan.Therefore
thatformisbestavoided.
Finally,youmaywanttofindtheindexofthelastelementofa
list.Todothisforthe@poorarrayusetheexpression
$#poor

Displayingarrays
Sincecontextisimportant,itshouldn'tbetoosurprisingthat
thefollowingallproducedifferentresults:
print@poor;#Byitself
print"@poor";#Embeddedindoublequotes
print@poor."";#Inascalarcontext

2.5Hashes(AssociativeArrays)
Ordinarylistarraysallowustoaccesstheirelementbynumber.
Thefirstelementofarray@pooris$poor[0].Thesecondelement
is$poor[1],andsoon.ButPerlalsoallowsustocreatearrays
whichareaccessedbystring.Thesearecalledassociativearrays
orhashes.
Todefineanassociativearrayweusetheusualparenthesis
notation,butthearrayitselfisprefixedbya%sign.Supposewe
wanttocreateanarrayofpeopleandtheirages.Itwouldlook
likethis:
%ages=("MichaelCaine",39,

"DirtyDen",34,
"Angie",27,
"Willy","21indogyears",
"TheQueenMother",108);

Nowwecanfindtheageofpeoplewiththefollowingexpressions
$ages{"MichaelCaine"};#Returns39
$ages{"DirtyDen"};#Returns34
$ages{"Angie"};#Returns27
$ages{"Willy"};#Returns"21indogyears"
$ages{"TheQueenMother"};#Returns108

Noticethatlikelistarrayseach%signhaschangedtoa$to
accessanindividualelementbecausethatelementisascalar.
Unlikelistarraystheindex(inthiscasetheperson'sname)is
enclosedincurlybraces,theideabeingthatassociativearrays
arefancierthanlistarrays.
Anassociativearraycanbeconvertedbackintoalistarrayjust
byassigningittoalistarrayvariable.Alistarraycanbe
convertedintoanassociativearraybyassigningittoan
associativearrayvariable.Ideallythelistarraywillhavean
evennumberofelements:
@info=%ages;#@infoisalistarray.It
#nowhas10elements
$info[5];#Returnsthevalue27from
#thelistarray@info
%moreages=@info;#%moreagesisanassociative
#array.Itisthesameas%ages

Operators
Associativearraysdonothaveanyordertotheirelements(they
arejustlikehashtables)butisitpossibletoaccessallthe
elementsinturnusingthekeysfunctionandthevaluesfunction:
foreach$person(keys%ages)
{
print"Iknowtheageof$person\n";
}
foreach$age(values%ages)
{
print"Somebodyis$age\n";
}

Whenkeysiscalleditreturnsalistofthekeys(indices)ofthe
associativearray.Whenvaluesiscalleditreturnsalistofthe
valuesofthearray.Thesefunctionsreturntheirlistsinthe
sameorder,butthisorderhasnothingtodowiththeorderin
whichtheelementshavebeenentered.
Whenkeysandvaluesarecalledinascalarcontexttheyreturn
thenumberofkey/valuepairsintheassociativearray.
Thereisalsoafunctioneachwhichreturnsatwoelementlistof
akeyanditsvalue.Everytimeeachiscalleditreturnsanother

key/valuepair:
while(($person,$age)=each(%ages))
{
print"$personis$age\n";
}

Environmentvariables
Whenyourunaperlprogram,oranyscriptinUNIX,therewillbe
certainenvironmentvariablesset.ThesewillbethingslikeUSER
whichcontainsyourusernameandDISPLAYwhichspecifieswhich
screenyourgraphicswillgoto.WhenyourunaperlCGIscripton
theWorldWideWebthereareenvironmentvariableswhichhold
otherusefulinformation.Allthesevariablesandtheirvaluesare
storedintheassociative%ENVarrayinwhichthekeysarethe
variablenames.Trythefollowinginaperlprogram:
print"Youarecalled$ENV{'USER'}andyouare";
print"usingdisplay$ENV{'DISPLAY'}\n";

2.6ControlStructures
Moreinterestingpossibilitiesarisewhenweintroducecontrol
structuresandlooping.Perlsupportslotsofdifferentkindsof
controlstructureswhichtendtobelikethoseinC,butarevery
similartoPascal,too.Herewediscussafewofthem.

foreach
Togothrougheachlineofanarrayorotherlistlikestructure
(suchaslinesinafile)Perlusestheforeachstructure.This
hastheform
foreach$morsel(@food)#Visiteachiteminturn
#andcallit$morsel
{
print"$morsel\n";#Printtheitem
print"Yumyum\n";#Thatwasnice
}

Theactionstobeperformedeachtimeareenclosedinablockof
curlybraces.Thefirsttimethroughtheblock$morselisassigned
thevalueofthefirstiteminthearray@food.Nexttimeitis
assignedthevalueoftheseconditem,andsountiltheend.If
@foodisemptytostartwiththentheblockofstatementsisnever
executed.

Testing
Thenextfewstructuresrelyonatestbeingtrueorfalse.In
Perlanynonzeronumberandnonemptystringiscountedastrue.
Thenumberzero,zerobyitselfinastring,andtheemptystring
arecountedasfalse.Herearesometestsonnumbersandstrings.

$a==$b#Is$anumericallyequalto$b?
#Beware:Don'tusethe=operator.
$a!=$b#Is$anumericallyunequalto$b?
$aeq$b#Is$astringequalto$b?
$ane$b#Is$astringunequalto$b?

Youcanalsouselogicaland,orandnot:
($a&&$b)#Is$aand$btrue?
($a||$b)#Iseither$aor$btrue?
!($a)#is$afalse?

for
PerlhasaforstructurethatmimicsthatofC.Ithastheform
for(initialise;test;inc)
{
first_action;
second_action;
etc
}

Firstofallthestatementinitialiseisexecuted.Thenwhiletest
istruetheblockofactionsisexecuted.Aftereachtimethe
blockisexecutedinctakesplace.Hereisanexampleforloopto
printoutthenumbers0to9.
for($i=0;$i<10;++$i)#Startwith$i=1
#Doitwhile$i<10
#Increment$ibeforerepeating
{
print"$i\n";
}

whileanduntil
Hereisaprogramthatreadssomeinputfromthekeyboardand
won'tcontinueuntilitisthecorrectpassword
#!/usr/local/bin/perl
print"Password?";#Askforinput
$a=;#Getinput
chop$a;#Removethenewlineatend
while($ane"fred")#Whileinputiswrong...
{
print"sorry.Again?";#Askagain
$a=;#Getinputagain
chop$a;#Chopoffnewlineagain
}

Thecurlybracedblockofcodeisexecutedwhiletheinputdoes
notequalthepassword.Thewhilestructureshouldbefairly
clear,butthisistheopportunitytonoticeseveralthings.
First,wecanwereadfromthestandardinput(thekeyboard)
withoutopeningthefilefirst.Second,whenthepasswordis
entered$aisgiventhatvalueincludingthenewlinecharacterat
theend.Thechopfunctionremovesthelastcharacterofastring

whichinthiscaseisthenewline.
Totesttheoppositethingwecanusetheuntilstatementinjust
thesameway.Thisexecutestheblockrepeatedlyuntilthe
expressionistrue,notwhileitistrue.
Anotherusefultechniqueisputtingthewhileoruntilcheckat
theendofthestatementblockratherthanatthebeginning.This
willrequirethepresenceofthedooperatortomarkthebeginning
oftheblockandthetestattheend.Ifweforgothesorry.Again
messageintheabovepasswordprogramthenitcouldbewritten
likethis.
#!/usr/local/bin/perl
do
{
print"Password?";#Askforinput
$a=;#Getinput
chop$a;#Chopoffnewline
}
while($ane"fred")#Redowhilewronginput

Exercise
Modifytheprogramfromthepreviousexercisesothateachlineof
thefileisreadinonebyoneandisoutputwithalinenumberat
thebeginning.Youshouldgetsomethinglike:
1root:oYpYXm/qRO6N2:0:0:SuperUser:/:/bin/csh
2sysadm:*:0:0:SystemVAdministration:/usr/admin:/bin/sh
3diag:*:0:996:HardwareDiagnostics:/usr/diags:/bin/csh
etc

Youmayfinditusefultousethestructure
while($line=<INFO>)
{
...
}

Whenyouhavedonethisseeifyoucanalteritsothatline
numbersareprintedas001,002,...,009,010,011,012,etc.To
dothisyoushouldonlyneedtochangeonelinebyinsertingan
extrafourcharacters.Perl'scleverlikethat.

ifelse
OfcoursePerlalsoallowsif/then/elsestatements.Theseareof
thefollowingform:
if($a)
{
print"Thestringisnotempty\n";
}
else
{
print"Thestringisempty\n";
}

Forthis,rememberthatanemptystringisconsideredtobefalse.
Itwillalsogivean"empty"resultif$aisthestring0.
Itisalsopossibletoincludemorealternativesinaconditional
statement:
if(!$a)#The!isthenotoperator
{
print"Thestringisempty\n";
}
elsif(length($a)==1)#Ifabovefails,trythis
{
print"Thestringhasonecharacter\n";
}
elsif(length($a)==2)#Ifthatfails,trythis
{
print"Thestringhastwocharacters\n";
}
else#Now,everythinghasfailed
{
print"Thestringhaslotsofcharacters\n";
}

Inthis,itisimportanttonoticethattheelsifstatementreally
doeshavean"e"missing.
Sometimes,itismorereadabletouseunlessinsteadofif
(!...).TheswitchcasestatementfamiliartoCprogrammersare
notavailableinPerl.Youcansimulateitinotherways.Seethe
manualpages.

Exercise
Fromthepreviousexerciseyoushouldhaveaprogramwhichprints
outthepasswordfilewithlinenumbers.Changeitsothatworks
withthetextfile.Nowaltertheprogramsothatlinenumbers
aren'tprintedorcountedwithblanklines,buteverylineis
stillprinted,includingtheblankones.Rememberthatwhenaline
ofthefileisreadinitwillstillincludeitsnewlinecharacter
attheend.

2.7Fileoperations
HereisthebasicperlprogramwhichdoesthesameastheUNIXcat
commandonacertainfile.
#!/usr/local/bin/perl
#
#Programtoopenthepasswordfile,readitin,
#printit,andcloseitagain.
$file='/etc/passwd';#Namethefile
open(INFO,$file);#Openthefile
@lines=<INFO>;#Readitintoanarray
close(INFO);#Closethefile
print@lines;#Printthearray

Theopenfunctionopensafileforinput(i.e.forreading).The

firstparameteristhefilehandlewhichallowsPerltoreferto
thefileinfuture.Thesecondparameterisanexpressiondenoting
thefilename.Ifthefilenamewasgiveninquotesthenitistaken
literallywithoutshellexpansion.Sotheexpression
'~/notes/todolist'willnotbeinterpretedsuccessfully.Ifyou
wanttoforceshellexpansionthenuseangledbrackets:thatis,
use<~/notes/todolist>instead.
TheclosefunctiontellsPerltofinishwiththatfile.
Thereareafewusefulpointstoaddtothisdiscussiononfile
handling.First,theopenstatementcanalsospecifyafilefor
outputandforappendingaswellasforinput.Todothis,prefix
thefilenamewitha>foroutputanda>>forappending:
open(INFO,$file);#Openforinput
open(INFO,">$file");#Openforoutput
open(INFO,">>$file");#Openforappending
open(INFO,"<$file");#Alsoopenforinput

Second,ifyouwanttoprintsomethingtoafileyou'vealready
openedforoutputthenyoucanusetheprintstatementwithan
extraparameter.ToprintastringtothefilewiththeINFO
filehandleuse
printINFO"Thislinegoestothefile.\n";

Third,youcanusethefollowingtoopenthestandardinput
(usuallythekeyboard)andstandardoutput(usuallythescreen)
respectively:
open(INFO,'');#Openstandardinput
open(INFO,'>');#Openstandardoutput

Intheaboveprogramtheinformationisreadfromafile.Thefile
istheINFOfileandtoreadfromitPerlusesangledbrackets.So
thestatement
@lines=<INFO>;

readsthefiledenotedbythefilehandleintothearray@lines.
Notethatthe<INFO>expressionreadsinthefileentirelyinone
go.Thisisbecausethereadingtakesplaceinthecontextofan
arrayvariable.If@linesisreplacedbythescalar$linesthen
onlythenextonelinewouldbereadin.Ineithercaseeachline
isstoredcompletewithitsnewlinecharacterattheend.

Exercise
Modifytheaboveprogramsothattheentirefileisprintedwitha
#symbolatthebeginningofeachline.Youshouldonlyhaveto
addonelineandmodifyanother.Usethe$"variable.Unexpected
thingscanhappenwithfiles,soyoumayfindithelpfultouse
thewoption.

Extendingpipes
Youcanveryeasilysubstitutereadingafiletoreadingapipe.
Thefollowingexampleshowsreadingtheouputofthepscommand.
open(PS,"psaef|")ordie"Cannotopenps\n";
while(){
print;
}
close(PS);

2.8StringProcessing
OneofthemostusefulfeaturesofPerl(ifnotthemostuseful
feature)isitspowerfulstringmanipulationfacilities.Atthe
heartofthisistheregularexpression(RE)whichissharedby
manyotherUNIXutilities.

Regularexpressions
Aregularexpressioniscontainedinslashes,andmatchingoccurs
withthe=~operator.Thefollowingexpressionistrueifthe
stringtheappearsinvariable$sentence.
$sentence=~/the/

TheREiscasesensitive,soif
$sentence="Thequickbrownfox";

thentheabovematchwillbefalse.Theoperator!~isusedfor
spottinganonmatch.Intheaboveexample
$sentence!~/the/

istruebecausethestringthedoesnotappearin$sentence.

The$_specialvariable
Wecoulduseaconditionalas
if($sentence=~/under/)
{
print"We'retalkingaboutrugby\n";
}

whichwouldprintoutamessageifwehadeitherofthefollowing
$sentence="Upandunder";
$sentence="BestwinklesinSunderland";

Butit'softenmucheasierifweassignthesentencetothe
specialvariable$_whichisofcourseascalar.Ifwedothis
thenwecanavoidusingthematchandnonmatchoperatorsandthe
abovecanbewrittensimplyas
if(/under/)
{

print"We'retalkingaboutrugby\n";
}

The$_variableisthedefaultformanyPerloperationsandtends
tobeusedveryheavily.

MoreonREs
InanREthereareplentyofspecialcharacters,anditisthese
thatbothgivethemtheirpowerandmakethemappearvery
complicated.It'sbesttobuildupyouruseofREsslowly;their
creationcanbesomethingofanartform.
HerearesomespecialREcharactersandtheirmeaning
.#Anysinglecharacterexceptanewline
^#Thebeginningofthelineorstring
$#Theendofthelineorstring
*#Zeroormoreofthelastcharacter
+#Oneormoreofthelastcharacter
?#Zerooroneofthelastcharacter

andherearesomeexamplematches.Rememberthatshouldbe
enclosedin/.../slashestobeused.
t.e#tfollowedbyanthingfollowedbye
#Thiswillmatchthe
#tre
#tle
#butnotte
#tale
^f#fatthebeginningofaline
^ftp#ftpatthebeginningofaline
e$#eattheendofaline
tle$#tleattheendofaline
und*#unfollowedbyzeroormoredcharacters
#Thiswillmatchun
#und
#undd
#unddd(etc)
.*#Anystringwithoutanewline.Thisisbecause
#the.matchesanythingexceptanewlineand
#the*meanszeroormoreofthese.
^$#Alinewithnothinginit.

Thereareevenmoreoptions.Squarebracketsareusedtomatchany
oneofthecharactersinsidethem.Insidesquarebracketsa
indicates"between"anda^atthebeginningmeans"not":
[qjk]#Eitherqorjork
[^qjk]#Neitherqnorjnork
[az]#Anythingfromatozinclusive
[^az]#Nolowercaseletters
[azAZ]#Anyletter
[az]+#Anynonzerosequenceoflowercaseletters

Atthispointyoucanprobablyskiptotheendanddoatleast
mostoftheexercise.Therestismostlyjustforreference.
Averticalbar|representsan"or"andparentheses(...)canbe

usedtogroupthingstogether:
jelly|cream#Eitherjellyorcream
(eg|le)gs#Eithereggsorlegs
(da)+#Eitherdaordadaordadadaor...

Herearesomemorespecialcharacters:
\n#Anewline
\t#Atab
\w#Anyalphanumeric(word)character.
#Thesameas[azAZ09_]
\W#Anynonwordcharacter.
#Thesameas[^azAZ09_]
\d#Anydigit.Thesameas[09]
\D#Anynondigit.Thesameas[^09]
\s#Anywhitespacecharacter:space,
#tab,newline,etc
\S#Anynonwhitespacecharacter
\b#Awordboundary,outside[]only
\B#Nowordboundary

Clearlycharacterslike$,|,[,),\,/andsoonarepeculiar
casesinregularexpressions.Ifyouwanttomatchforoneof
thosethenyouhavetopreceeditbyabackslash.So:
\|#Verticalbar
\[#Anopensquarebracket
\)#Aclosingparenthesis
\*#Anasterisk
\^#Acaratsymbol
\/#Aslash
\\#Abackslash

andsoon.

SomeexampleREs
Aswasmentionedearlier,it'sprobablybesttobuildupyouruse
ofregularexpressionsslowly.Hereareafewexamples.Remember
thattousethemformatchingtheyshouldbeputin/.../slashes
[01]#Either"0"or"1"
\/0#Adivisionbyzero:"/0"
\/0#Adivisionbyzerowithaspace:"/0"
\/\s0#Adivisionbyzerowithawhitespace:
#"/0"wherethespacemaybeatabetc.
\/*0#Adivisionbyzerowithpossiblysome
#spaces:"/0"or"/0"or"/0"etc.
\/\s*0#Adivisionbyzerowithpossiblysome
#whitespace.
\/\s*0\.0*#Asthepreviousone,butwithdecimal
#pointandmaybesome0safterit.Accepts
#"/0."and"/0.0"and"/0.00"etcand
#"/0."and"/0.0"and"/0.00"etc.
#Checkforvalidcurrencyvalue
^([09]+|[09]{1,3}(,[09]{3})*)(\.[09]{1,2})?$
#Checkforvalidemailaddress
^[_az09]+(\.[_az09]+)*@[az09]+(\.[az09]+)*$

Exercise
Previouslyyourprogramcountednonemptylines.Alteritsothat
insteadofcountingnonemptylinesitcountsonlylineswith

theletterx
thestringthe
thestringthewhichmayormaynothaveacapitalt
thewordthewithorwithoutacapital.Use\btodetectword
boundaries.

Ineachcasetheprogramshouldprintouteveryline,butit
shouldonlynumberthosespecified.Trytousethe$_variableto
avoidusingthe=~matchoperatorexplicitly.

Substitution&Translation
JustlikethesedandtrutilitiesinUnix,youhaves///and
tr///inPerl.Theformerisforsubstitutionandthelaterisfor
translation.
$bar=~s/this/that/g;#changethistothatin$bar
$path=~s|/usr/bin|/usr/local/bin|;
s/\bgreen\b/mauve/g;#don'tchangewintergreen
s/Login:$foo/Login:$bar/;#runtimepattern
$count=($paragraph=~s/Mister\b/Mrg);#getchangecount
$program=~s{
/\*#Matchtheopeningdelimiter.
.*?#Matchaminimalnumberofcharacters.
\*/#Matchtheclosingdelimiter.
}[]gsx;#Delete(most)Ccomments.
s/^\s*(.*?)\s*$/$1/;#trimwhitespacein$_,expensively
for($variable){#trimwhitespacein$variable,cheap
s/^\s+//;
s/\s+$//;
}
s/([^]*)*([^]*)/$2$1/;#reverse1sttwofields
#Notetheuseof$insteadof\inthelastexample.Unlikesed,
#weusethe\forminonlythelefthandside.
#Anywhereelseit's$.
$myname="BABU";
$myname=~tr/[AZ]/[az]/;#yieldsbabu

Splitting
Perlprovidesasplitfunctiontosplitstrings,basedonREs.The
syntaxis
split/PATTERN/,EXPR,LIMIT
split/PATTERN/,EXPR
split/PATTERN/
split

IfEXPRisomitted,$_isused.IfPATTERNisalsoomitted,splits
onwhitespaces,afterskippingleadingwhitespaces.LIMITsetsthe
maximumfieldsreturnedsothiscanbeusedtosplitpartially.
Someexamplesaregivenbelow:
#processthepasswordfile
open(PASSWD,'/etc/passwd');
while(){
($login,$passwd,$uid,$gid,
$gcos,$home,$shell)=split(/:/);
#notethat$shellstillhasanewline.
#usechoporchomptoremovethenewline
#...
($login,$passwd,$remainder)=split(/:/,$_,3);
#hereweuseLIMITtosetthenumberoffields
}

Wealsohavejoinwhichistheoppositeofsplit.Forfixedlength
strings,wehaveunpackandpackfunctions.

2.9Subroutines
LikeanygoodprogramminglanguagePerlallowstheusertodefine
theirownfunctions,calledsubroutines.Theymaybeplaced
anywhereinyourprogrambutit'sprobablybesttoputthemallat
thebeginningorallattheend.Asubroutinehastheform
submysubroutine
{
print"Notaveryinterestingroutine\n";
print"Thisdoesthesamethingeverytime\n";
}

regardlessofanyparametersthatwemaywanttopasstoit.All
ofthefollowingwillworktocallthissubroutine.Noticethata
subroutineiscalledwithan&characterinfrontofthename:
&mysubroutine;#Callthesubroutine
&mysubroutine($_);#Callitwithaparameter
&mysubroutine(1+2,$_);#Callitwithtwoparameters

Parameters
Intheabovecasetheparametersareacceptablebutignored.When
thesubroutineiscalledanyparametersarepassedasalistin
thespecial@_listarrayvariable.Thisvariablehasabsolutely
nothingtodowiththe$_scalarvariable.Thefollowing
subroutinemerelyprintsoutthelistthatitwascalledwith.It
isfollowedbyacoupleofexamplesofitsuse.
subprintargs
{
print"@_\n";
}
&printargs("perly","king");#Exampleprints"perlyking"
&printargs("frog","and","toad");#Prints"frogandtoad"

Justlikeanyotherlistarraytheindividualelementsof@_can
beaccessedwiththesquarebracketnotation:
subprintfirsttwo
{
print"Yourfirstargumentwas$_[0]\n";
print"and$_[1]wasyoursecond\n";
}

Againitshouldbestressedthattheindexedscalars$_[0]and
$_[1]andsoonhavenothingtowiththescalar$_whichcanalso
beusedwithoutfearofaclash.

Returningvalues
Resultofasubroutineisalwaysthelastthingevaluated.This
subroutinereturnsthemaximumoftwoinputparameters.Anexample
ofitsusefollows.
submaximum
{
if($_[0]>$_[1])
{
$_[0];
}
else
{
$_[1];
}
}
$biggest=&maximise(37,24);#Now$biggestis37

The&printfirsttwosubroutineabovealsoreturnsavalue,inthis
case1.Thisisbecausethelastthingthatsubroutinedidwasa
printstatementandtheresultofasuccessfulprintstatementis
always1.

Localvariables
The@_variableislocaltothecurrentsubroutine,andsoof
courseare$_[0],$_[1],$_[2],andsoon.Othervariablescanbe
madelocaltoo,andthisisusefulifwewanttostartaltering
theinputparameters.Thefollowingsubroutineteststoseeifone
stringisinsideanother,spacesnotwithstanding.Anexample
follows.
subinside
{
local($a,$b);#Makelocalvariables
($a,$b)=($_[0],$_[1]);#Assignvalues
$a=~s///g;#Stripspacesfrom
$b=~s///g;#localvariables
($a=~/$b/||$b=~/$a/);#Is$binside$a
#or$ainside$b?
}
&inside("lemon","dolemoney");#true

Infact,itcanevenbetidiedupbyreplacingthefirsttwolines
with
local($a,$b)=($_[0],$_[1]);

Vous aimerez peut-être aussi