Académique Documents
Professionnel Documents
Culture Documents
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]);