如此,便可以直接執行這個程式,此程式的第一行便會告訴作業系統到哪裡去找到執行這個perl的程式。
在Windows NT中執行PERL程式 前面所提到的東西在UNIX 中可以很正常的 ...
²Ä¤@³¹Perl·§z
byPaulDoyle½Ķ¡G¼B´¼º~
¥Ø¿ý
Perl
°_·½Origins
ɥΪº·§©À
±ÂÅv¤Î¶O¥Î
³nÅé´²¼½
PERLµ{¦¡
©I¥sPerl
©R¥O¦C°Ñ¼Æ
ProgramLayout
¸ê®Æ«¬ºA
¼ÆÈ«¬ºA
°}¦C
°}¦C²Õ¦XAssociativeArrays
Àɮ׳B²z
¯S®íÅܼÆ
Àô¹ÒÅܼÆ
ProgramArguments
CurrentLine
¨t²Î¿ù»~°T®§
¬yµ{±±¨î¡]FlowControl¡^
ÅÞ¿è¹Bºâ¤¸
±ø¥ó¦¡»yªkªí¥Ü
½Æ¦X»yªk
°j°é
Labels
¤lµ{¦¡¡]Subroutines¡^
Åܼƽd³ò¡]VariableScope¡^
Patterns
¥¿³WºÙªk¡]RegularExpressions¡^
Matching
Substitution
FromHere
·í§An¦bwwwservers¤W¨Ï¥ÎPerl¤§«e¡A§A¥²¶·nªá¶OÂI®É¶¡¨Ó¤F¸ÑPerl³oÓµ{¦¡
»y¨¥¡C¥»³¹´£¨Ñ¤FPerl»y¨¥ªº·§Æ[¡CÁöµM¥¦¤£¬OPerl»y¨¥ªº®Ö¤ß¡A¦ý¤]¨¬°÷¥h¨Ï¥Î
Perl¤F¡C´N¹³§A¨Ï¥Î»y¨¥¤@¼Ë¡A·í§A¨Ï¥ÎPerl³]p¤F¤@¬q®É¶¡¤§«á¡A§A«K·|·Qn¥hÆp¬ã§ó
²`ªºªF¦è¡C
The"CamelBook"
·í§A·Ç³Æ¾Ç²ß§ó¦h®É¡A§A¥i¯à·|·Qn¥hÁʶRProgrammingPerl
³o¥»¥ÑLarryWallandRandalL.Schwartz©ÒµÛªº®Ñ¡C(O'Reilly&
Associates,Inc.).¥»®Ñ¬O¥Ø«e¨Ï¥ÎPerl³Ì¥i¾aªº®Ñ
¥Lªº¥iŪ©Ê¤Î«ÕÀq©Ê¨ì¥Ø«e¬°¤î¤´µM¦³¨¬°÷ªº§Þ³N¥i¨Ñ¦b¥ô¦óPerl
ªºµ{¦¡³]p¤W¨Ï¥Î¡C
¥Ñ©ó¨Ï¥Î¤@°¦³æ®pÀd¾m§@¬°«Ê±¡A¦]¦¹¥»®Ñ«K¦³¤F"Camelbook"ºÙ¸¹¡C
¥Ñ©ó«Ü¦h¾Ç²ßPerlªº¤H¨Ï¥Î³o¥»®Ñ§@¬°¾Ç²ß¤â¥U¡A¦]¦¹³o°¦°Êª«¤w¸gÅܦ¨¤FPerl»y¨¥ªº¶H
¼x¼Ð»x¤F¡]¦³ÂI¹³Linuxªº¥øÃZ¡^¡C
¥»³¹¸`§Ṳ́£·|¥h¬ã¨s¤Ó²`ªºªF¦è¡A©Ò¦³²`¤Jªº½ÒÃD§ÚÌ·|¦b¥»®Ñªº²Ä¤³¡¤À¨Ó±´°Q¡C
¥»³¹µ²§ô¤§«á¡A,§AÀ³¸Óª¾¹Dn¥hþ¸Ì§ä¨ì¤@¨Ç¯S©w°ÝÃDªºµª®×¡C¦pªG§A¹ïPerl¤w¸g
¦³¨Ç¤F¸Ñ¡A§A¥i¥H¸õ¹L¥»³¹¥h´M§ä§A·Qn¾Ç²ßªº³¡¤À¡C¦pªG§A®Ú¥»´N¤£¼ô±x¥ô¦ó¤@ºØµ{
¦¡»y¨¥¡A¥»®Ñ¨Ã¤£¾A¦X§@¬°ªì¾ÇªÌ¾Ç²ßµ{¦¡»y¨¥ªº¤Jªù®ÑÄy¡C
Perl
®Ú¾Úì§@ªÌªº¦Ûz¡APerl·|³Qµo®i¥X¨Ó°_¦]¨ä¹ê¬O¦]¬°¬Y¤H¹L«×Ãi´kªºµ²ªG¡C
NOTE
³oÓ³¡¤ÀÀ³¸Ó¥i¥HÀH«K±a¹L´N¥i¥H¤F¡A¬°¤°»ò§Ún®ö¶O®É¶¡¦b³o¸Ì©O¡H¨Æ¹ê¤W¡A
Perl¬O¤@ºØ¯S®íªº»y¨¥¡A¥L¤£¯à©M¤@¯ëªº¥H§Þ³N¬°¥Dµ{¦¡»y¨¥¨Ó¤ñ¸û¡C§Ṳ́£¯à¥u§â¥¦·í
§@¬O¤@ºØµ{¦¡»y¨¥¨Ó¬Ý¡C©Ò¥H§ÚÌnªá¤@¨Ç®É¶¡¨Ó¬ã¨s¥L¬O¦p¦ó³Q¬ãµo¥X¨Ó¡A¬°¤°»ònµo
®iPerl¡H
°_·½
Åý§Ú̦^¨ì1986¦~¡A·í®É¦³Ó¦W¥sLarryWallªºUNIXµ{¦¡³]p®v¡Aµo²{¨ì¥L¨C¤Ñ³£±o
©M¬°¼Æ²³¦h¤S½ÆÂøªº¤å¥ó³ø§i¬°¥î¡A¦]¦¹¥L¶}©l¨Ï¥Îawk¨Ó³B²z³o¨Ç¤å¥ó¡C¤£¤[¡A¥Lµo²{
¨ìawk¤£¯à²Å¦X¥Lªº»Ý¨D¡A¦b§ä¤£¨ì¨ä¥¦¦X¥Îªº¤u¨ãªº±¡ªp¤U¡A¥L¨M©w¦Û¤v¼g¤@¨Ç
µ{¦¡¡A¨Ó¸Ñ¨M³o¨Ç§xÂZ¥L³\¤[°ÝÃD¡C
Larry¼g¤F¤@¨Ç¤½¥Îµ{¦¡¨ÓºÞ²z¥L¤u§@¤Wªº¯S®í»Ý¨D¡C¦ý¬O¤£¤[³o¨Ç¤u§@¯S©Ê¤SÅܤF¡A
©ó¬O¥L¤S¥²¶·n«¼g¤@¨Ç¤u¨ã¨ÓÀ³¥I·sªº¤u§@»Ý¨D¡C¬°¤F¤£®ö¶O®É¶¡¡A¥Lµo©ú¤F·sªºµ{¦¡»y
¨¥¡A¨Ã¥B¬°³oÓ»y¨¥¼g¤FÓª½Ä¶¾¹¡C¥Lµo©úªº»yªk¬Ý°_¨Ó¹³¬Oparadox¡A¦ý¨Æ¹ê¤W«o¤£µM¡C
·sªº»y¨¥¥[±j¤F¹ï¨t²ÎªººÞ²z¤Î¤å¦rªº³B²z¡A¸g¹L´X¦¸§ïª©¤§«á¡A·sªº»y¨¥¥i¥H³B²z¥¿
³Wªº»yªk¡A²Å¸¹¡A¥H¤Îºô¸ô³q«H¨ó©w¡C³o´N¬O²{¦b»D¦WªºPerl»y¨¥¡C
ɥΪº·§©À
Perl±q¨ä¥¦ªº¤u¨ãɤF³\¦hªF¦è¨Ó¨Ï¥Î¡A¯S§O¬Osed¤Îawk.ÁöµMPerl§@ªº³\¦h¨Æ±¡
¥Îsed,awk©Î¬OUNIXshellscripting»y¨¥¨Ó§@¡A³£¥i¥H±o¨ì¬Û¦Pªºµ²ªG¡A¦ý¬OPerl·|
§@ªº¤ñ¸û¦n¡C
NOTE
¨s³ºn¥Î¤j¼gªºPerl©Î¬O¤p¼gªºperl©O¡H®Ú¾ÚLarryWall
ªº©w¸q¡G³o®Ú¥»¬O¤@¥ó¤£«nªº¨Æ¡C¦ý¬O³\¦hµ{¦¡³]p®v«o¤ñ¸û³ßÅw¨Ï¥ÎPerl¡C³q
±`UNIX¨t²Î¤Wªºµ{¦¡³£¶É¦V©ó¨Ï¥Î¤p¼g¡C¤£ºÞ¦p¦ó¡A¿ï¾Ü§A³ßÅwªº¤è¦¡¥hºÙ©I¥L¡A²¦³º
Perl¬O¤@Ó¤u¨ã¡A¤£¬O±Ð±ø¡C
¦pªG§A·Qn½æ§Ë¾Ç°Ý¡A¦b¾\Ū§¹¥»³¹ªº¡e¥¿³WºÙªk¡f³oÓ³¡¤À«á¡A§A¥i¯à·|ºÙ¥L
¬°[Pp]erl
Perl¥i¥H±N§C¶¥ªºªF¦è³B²zªº«D±`¦n¡A¯S§O¬OPerl5¡C¥L¦³³\¦h³B²z¤è¦¡©MC¬O¬Û³q
ªº¡A¦ý¬OPerl³B²z¸ê®Æ«¬ºA¡A°O¾ÐÅé°t¸m¡A«o¤ñC¨Óªº§ó¦Û°Ê¤Æ¡C
Perlµ{¦¡½X¤]§e²{¥X©MCªºµ{¦¡½X¬Û¦ü¡C¤]³\³o¬O¦]¬°Perl¬O¥ÎC¼g¦¨ªº¡A¤]¥i¯à¬O
Larryµo²{¥ÎCªº»yªk¨Ó§@ªí¹F·|§ó®e©ö¤W¤â¡CÁö¬O¦p¦¹¡APerl«o¦³µÛ¤ñC§ó²¼äªº»y
ªk¡C
¶O¥Î¤Î±ÂÅv
Perl¬O¤@®M§K¶Oªº¤u¨ã¡C¥þ³¡ªºsource¥H¤Î¤å¥ó³£¥i¨Ñ¤H§K¶O½Æ»s¡A½sĶ©Î¬O¦C¦L
¡C·í§A´²¼½³nÅé®É§A¨Ã¤£»Ýn¥Iµ¹¥ô¦ó¤Hª©µ|¡A¤]¨S¦³¥ô¦óªºªk«ß¬ù§ô¡C
Perl¤´µM¬O¤@Ó«O¦³µÛ§@Åvªº²£«~¡A°²¦pì©lµ{¦¡½X³Q§¹¥þ¤½¶}¡A¬Y¤H¥i¯à´N·|¹ïµ{¦¡§@
¤Ö³¡¤Àªº×§ï¡AµM«á«·s½sĶ±µµÛ«K¥Î¨ä¥Lªº²£«~¦WºÙ¥h³c½æ¦È§Q¡C
GNU²Õ´¬O¤@Ó¥i¥H«OÅ@´²¼½ªº§K¶O³nÅé³Q«§ï¦È§Qªº²Õ´¡C¦b¥Lªº±ÂÅv¤§¤U¡Aì©l½X¥i
¥H³Q¥ô¦ó¤H§K¶Oªº¨Ï¥Î¡A¦ý¬O¥ô¦ó®Ú¾Úì©l½X©Òµo®i¥X¨Óªºµ{¦¡¤]¥²¶·¥Î¦P¼Ëªº¤è¦¡¨Ó´²
¼½¥X¥h¡C´«¥y¸Ü»¡¡A¦pªG§A¥Î¨Óµo®i©pµ{¦¡ªºì©l½X¬O¦bGNU±ÂÅv¤§¤U¨ú±oªº¡A¨º§A¤]¥²
¶·±N§Aªºì©l½Xµ¹¥ô¦ó¦³»Ýnªº¤H¡C
³oºØ¤è¦¡¥i¥H´£¨Ñ¹ï³nÅéµo®i¦³¿³½ìªº¤H¤@¶µ¥R¤Àªº«OÅ@¡A¦ý«o¥i¯à²£¥Í¥X¹L¦hªºÃþ¦üµ{
¦¡¥X¨Ó¡A³o¥i¯à·|³y¦¨³Ù»«¹Ü¥Dªº±¡ªpµo¥Í¡C¤]¥i¯à·|³y¦¨ª©¥»±±¨î¤Wªº°ÝÃD¡A¥i¯à¬Y¨Ç
¯S©wªºµ{¦¡»Ýn¦b¬Y¨Ç¯S©wªºª©¥»¤W°õ¦æ¡A¦ý«o¥Î¤F¤£¦Pªºª©¥»¡A¦p¦¹¤@¨Ó¡A¹ï¨Ï¥ÎªÌ«K·|
³y¦¨¬Û·í¤jªº§xÂZ¡C
³o«K¬O¬°¤°»òPerl·|¦bArtisticLicense³oÓ¾÷ºc¤Uµoªíªºì¦]¡C³oÓ¾÷ºcªº²z©À¤£¦P
©óGNU¡CArtisticLicenseªí¥Ü¦pªG¦³¤H¨Ï¥Î¤FPerlªºì©l½X¨Óµo®i¥L̦ۤvªºµ{¦¡¡A
¥L¥²¶·©ú¥Õ¦aªí¥Ü¥L©Òµoªíªº³nÅé¨Ã¤£¬OPerl¡C©Ò¦³§ó§ïªº³¡¤À³£¥²¶·©ú¥Õªº«ü¥X¨Ó¡A
¦Ó¥B°õ¦æÀɤ£¯à©M³Q§ó§ïªºµ{¦¡¦P¦W¡C¦pªG¦³¥²nªº¸Ü¡Aì©lµ{¦¡½X¥²¶·©M§ó§ï¹Lªºµ{¦¡
¤@°_³Q´²¼½¥X¥h¡C³oºØµ²ªG·|Åýì§@ªÌ³Q²M·¡ªº»{¦P¬°¦¹®M³nÅ骺ì§@ªÌ¡C
³nÅé´²¼½
·sª©¥»ªºPerl¥i¥H¦bºô¸ô¤W©Î¬O¦UFTP¯¸¤W§ä¨ì¡CPerlªºì©l½X¥H¤Î¤å¥ó¥i¥H¦b«DUNIX
¨t²Î¤W°õ¦æ¡CUNIXªº¤G¦ì¤¸Àɳq±`¦bºô¸ô¤W§ä¤£¨ì¡A³o¬O¦]¬°´X¥G©Ò¦³ªºUNIX¨t²Î³£¦³
C»y¨¥½sĶ¾¹¡A§A¥i¥H¥Î¤ºªþªºC½s¿è¾¹¦b§Aªº¾÷¾¹¤W«·s²ÕĶ¤@¦¸¡A¥H½T«OPerl¯à¦b
©pªº¨t²Î¤W°õ¦æ¡A³oºØ¤è¦¡¤ñ¦b§O¤H¾÷¾¹¤W²ÕĶPerlµ{¦¡«á¡A¦A²¾¨ì§Aªº¹q¸£¤W·|¦nªº
¦h¡C
Perl®M¥ó³q±`³£·|¦ñÀHµÛ¤@®MºÙ¬°Configureªº¤½¥Îµ{¦¡¡A¥¦¥i¥H®Ú¾Ú¤£¦Pªº¹q¸£¥D¾÷ª¬
ªp¦Û°ÊÀ°§A³]©w¦nì©l½X¥H¤Îmakefile¡C¥L·|¦Û°Ê°»´ú¨t²Î¤ºªº²ÕºA¡AµM«á¨Ì¾Ú¤£¦Pªºª¬
ªpÀ°§A§â²ÕĶPerlªº»Ýn°T®§³£³]©w¦n¡A·íµM¡A§A¤]¥i¥H¦Û¦æ¥h³]©w³o¨Ç°T®§¡C
Perlµ{¦¡³]p¡]Perl
Programs¡^
·í§A¦w¸Ë§¹perl¤§«á¡A§An¦p¦ó¨Ï¥Î³oÓ©_§®ªº¤u¨ã¨Ó¨Ïºô¯¸§ó¦hªö¦h«º©O¡H¤°»ò¬O
Perlªºµ{¦¡³]p¡H§An¦p¦ó¨Ó¨Ï¥Î¥¦©O¡H
©I¥sPerl
§ÚÌ¥´ºâ¦b¥»³¹¸`ªº³Ì«á¤~¨Ó¦^µª«e±ªº¨âÓ°ÝÃD¡C©Ò¥H§Ú̪½±µ¨Ó±´°Q²Ä¤TÓ°ÝÃD¡A
¨Ï¥Î
perl¬O¤@¥ó·¥Â²³æªº¨Æ¡A¦ý¬Oµ{§ÇÅܼơ]procedurevaries¡^«o·|¦]¬°¤£¦Pªº¨t²Î¦Ó¦³¨Ç³\ªºÅܤơC
º¥ý°²³]perl¤w¸g¥¿½Tªº¦w¸Ë¦b§Aªº¹q¸£¤W¤F¡C°õ¦æperl
ªº³Ì²³æªº¤èªk´N¬O¥h±Ò°Êperlª½Ä¶¾¹¡A´N¹³¤U±¤@¼Ë¡G
perlsample.pl
¦b³oÓ½d¨Ò¤¤¡ASAMPLE.PL¬OperlÀɮתº¦WºÙ¡A¦Óperl«h¬Operlª½Ä¶¾¹¡C
³oÓ½d¨Ò°²³]perl¬O¥Ø«eªº°õ¦æ¸ô®|¡A¦pªG¤£¬Oªº¸Ü¡A§A¥²¶·nµ¹©wperlªº©Ò
¦b¸ô®|¡A´N¹³¤U±¤@¼Ë¡G
/usr/local/hin/perlsample.pl
³oÓ»yªk¬O°õ¦æperl
®Éªº³Ì¦n»yªk¡C¦]¬°¥L±Æ°£¤F§A¥i¯à·|©I¥s¨ì¨ä¥¦ª©¥»perl
¦Ó¤£¬O§A·Qn°õ¦æªºª©¥»¡C¦]¬°§Ú̱N·|¦bWebservers
¤W°õ¦æ§Ú̪ºµ{¦¡¡A¦]¦¹¡A³Ì¦nÁÙ¬O¨Ï¥Î§¹¾ãªº¸ô®|¥HÁקK¥X¿ù¡C
´X¥G¨C¤@ºØ¨t²Î³£¦³©R¥O¦Cªº¤¶±¡]command-lineinterface¡^¡C¦b¨Ï¥Î
WindowsNT®É¦³Ó¤p³Z¬¡G
c:\NTperl\perlsample.pl
¦bUNIX¤¤°õ¦æperl¡G UNIX
¨t²Î¦³¥t¥~¤@ºØ°õ¦æ¤èªk«K¬O¥i¥H¦bscriptÀɤ¤°õ¦æperlµ{¦¡¡C§A¥i¥H¦b
perlÀɮפ¤ªº²Ä¤@¦æ©ñ¸m¤U¦Cªº±Ôz¡AÅýµ{¦¡¦Û°Ê¥h°õ¦æperlµ{¦¡¡G
#!/usr/local/bin/perl
³o¤@¦æ§i¶DUNIX³oÓµ{¦¡¬O¥Ñ³oÓ/USR/LOCAL/BIN/PERL¸ô®|ªºperl
µ{¦¡¥h½Ķ©³¤Uªº©R¥O¡A¦p¦¹©p´N¥i¥HÅýµ{¦¡¦Û¦æ¥h°õ¦æ¡A¦ýn§@¥H¤Uªº×§ï¡G
chmod+xsample.pl
¦p¦¹¡A«K¥i¥Hª½±µ°õ¦æ³oÓµ{¦¡¡A¦¹µ{¦¡ªº²Ä¤@¦æ«K·|§i¶D§@·~¨t²Î¨ìþ¸Ì¥h§ä¨ì°õ¦æ³oÓ
perlªºµ{¦¡¡C
¦bWindowsNT¤¤°õ¦æPERLµ{¦¡
«e±©Ò´£¨ìªºªF¦è¦bUNIX¤¤¥i¥H«Ü¥¿±`ªº°õ¦æ¡A¦ý¬O¦bWindowsNT¤¤´N¤£¨£±o¥i¥H°õ¦æ
¡C§A¥i¥H¨Ï¥ÎNTªºÀɮ׺޲zû¨Ó«Ø¥ßªþÀɦW¬°.PLªºÀɮשMPerlªºÀÉ®×ÃöÁp¡A³o¼Ë
Perl´N¥i¥H¦bNT¤¤°õ¦æ¡C¥un¬OªþÀɦW¬°.PlNT´Nª¾¹D³o¬OPerlµ{¦¡¡A´N·|¦Û°Ê¥h
©I¥sPerl¨Ó°õ¦æ³oÓªþÀɦW¬°.PLªºµ{¦¡¡C
³Æµù
³q±`§ÚÌÁÙ»Ýn´XÓ¨BÆJ¤~¯àÅýWebserver¦Û°Ê¥h°õ¦æPerlµ{¦¡¡C
°Ñ¾\ªþ¿ýA"Perl¨ú±o¤Î¦w¸Ë"¡Ð¦b¯S©wªº¥¥x¤W«Ø¥ßscripts¤Îª½Ä¶¾¹ªºÃö
Áp©Ê¡C
©R¥O¦C°Ñ¼Æ
Perl´£¨Ñ¤F¦UºØ°w¹ï¤£¦P¥Øªº¦Ó¨Ï¥Îªº°Ñ¼Æ¡]°Ñ¾\Table1.1¡A¤j³¡¤Àªº°Ñ¼Æ³£¦C¦b³o
¸Ì¡^¡C
the-tswitchinparticularisderigueurinWeb-basedPerlscripts.
Table1.1 Perl©R¥O¦C°Ñ¼Æ
°Ñ¼Æ
¥\¯à
¨Ï¥Î¥Øªº
³Æµù
-0
Octalcharactercode
Specifyrecordseparator
Defaultisnewline(\n)
-a
Automaticallysplitrecords
Usedwith-nor-p
-c
Checksyntaxonlydonotexecute
-d
Runscript,usingPerldebugger
IfPerldebuggerisinstalled
\-D
Flags
Specifydebuggingbehavior
RefertothePERLDEBUGmanpageontheCD-ROMthatcomeswiththisbook
-e
Command
PassacommandtoPerlfromthecommandline
Usefulforquickoperations;seetipafterthistableforanexample
-F
Regularexpression
Expressiontosplitbyif-aisused
Defaultiswhitespace
-i
Extension
Replaceoriginalfilewithresult
Usefulformodifyingcontentsoffiles;seetipafterthistableforan
example
-I
Directory
Specifylocationofincludefiles
-l
Octalcharactercode
Dropnewlineswhenusedwith-nand-p,anduse
designatedcharacterasline-terminationcharacter
¡@
-n
Processthescript,usingeachspecifiedfileasanargument
Usedforperformingthesamesetofactionsonasetoffiles
-p
Sameas-n,buteachlineisprinted
¡@
-P
RunthescriptthroughtheCpreprocessorbeforePerlcompilesit
¡@
-s
EnablepassingofarbitraryswitchestoPerl
Use-s-what-evertohavethePerlvariables$whatand$ever
definedwithinyourscript
-S
TellPerltolookalongthepathforthescript
¡@
-T
Usetaintchecking;don'tevaluateexpressionssuppliedinthecommand
line
VeryimportantforWebuse
-u
MakesPerldumpcoreaftercompilingyourscript;intendedtoallowfor
generationofPerlexecutables
Verymessy;waitforthePerlcompiler
-U
¤£¦w¥þ¼Ò¦¡;overridesPerl'snaturalcaution.
ºÉ¶q¤£n¨Ï¥Î¡I
-v
Åã¥ÜPerlª©¥»
-w
¦L¥X»yªk¿ù»~ªºÄµ§i»y
«D±`¦³¥Î¡A¯S§O¬O¦bµo®i¶¥¬q
TIP
The-eoptionishandyforquickPerloperationsfromthecommandline.Want
tochangeallthefoosinWIFFLE.BATtobars?Trythis:
perl-i.old-p-e"s/foo/bar/g"wiffle.bat
Thiscodesays,"TakeeachlineofWIFFLE.BAT(-p),storetheoriginalin
WIFFLE.OLD(-i),replaceallinstancesoffoowithbar(-e),
andwritetheresult(-p)totheoriginalfile(-i)."
§A¥i¥H¦bUNIX¤¤¨Ï¥ÎPerl©R¥O¦C°Ñ¼Æ¡A©³¤U§Y¬°½d¨Ò¡G
#!/usr/local/bin/perl-w-T
ª`·N¨Æ¶µ
The-wswitchisbestomittedinversionsofPerlolderthan5.002,becauseit
mayproducespuriouswarnings.
Also,takecarewhenyouusethe-wswitchinscriptsthatsenddatatoWeb
browsers.Warningmessagessentbeforethebrowserreceivesacontent-typelinemayresult
inanerrormessage.
µ{¦¡ªº§G§½¡]ProgramLayout¡^
¤@ÓPerlµ{¦¡¬O¥Ñ¥]§t¤F¤£¦Pªºperl©R¥Oªº
¤å¦rÀÉ©Ò²Õ¦¨¡C³o¨Ç©R¥O¬O¥Ñ¤@¨Ç¬Ý°_¨Ó«D±`¹³C,shellscript,
¥H¤Î^¤å©Ò²Õ¦¨¡C
Perlµ{¦¡¥i¥H¬O«D±`¦Û¥Ñªº§Î¦¡¡A¦]¬°¥Lªº»yªk³W«h«D±`¼eÃP¡G
¶}ÀYªºªÅ¶¡·|³Qµ{¦¡©¿²¤¡C§A¥i¥H¦b¥ô¦ó§A³ßÅwªº¦a¤è¶}©lPERL
ªºµ{¦¡¡C¥un§A³ßÅw¡A§A¥i¥H¦b²Ä¤@¦æ¶}©l¡A©Î¬O¨Ï¥Î¶Ç²Îªº¶¥¼h¦¡»yªk¡]«Øij¨Ï¥Î¡^¡A©Î¬O¦Û³Ðªº§Î¦¡¡]¥un§A¬ÝªºÀ´¡^¡C
µ{¦¡¬O¥Î¤À¸¹¡]¡F¡^§@¬°µ²§ô¡C
¤@ӪŮæ©M¤@¦ÊӪŮæ¬O¤@¼Ë¦nªº¡C³o¤]´N¬O»¡§A¥i¥H±N¤Óªøªº±Ôz¦¡¤À³Î¦¨¼Æ¦æ¥H¤è«K¾\Ū¡C
¦b³oӲŸ¹(#)«á¤èªº¥ô¦óªF¦è³£·|³Q©¿²¤¤£¥h°õ¦æ¡C
©³¤U´N¬O¤@ÓPerlªí¹F¦¡¡G
print"MynameisAndyLiu\n;
·íPerl°õ¦æ¤W±³oÓµ{¦¡®É¡A·|¦b¿Ã¹õ¤W¦L¥X¡GMynameisAndy
Liu¡C·íperlµ{¦¡°õ¦æ¨ì \n ®É¡Aµ{¦¡·|¦Û°Ê´«¦æ¡C
¡]¥Î¨ä¥Lªº¸Ü¨Ó»¡¡A´N¬O¸õ¨ì¤U¤@¦æªº¶}ÀY¡^¡C
¦C¦L§ó¦h¦æªº¤èªk¡A´N¬O±N¤W±ªº¨Ò¤l°õ¦æ¦h¦¸ªºµ²ªG¡C
print"MynameisYonYonson,\n";
print"IliveinWisconsin,\n",
"Iworkinalumbermillthere.\n";
§¹¾ãªºPerlµ{¦¡¬Ý°_¨Ó¹³¤°»ò©O¡H©³¤U¬O¤@ÓUNIX
ªº½d¨Ò¡A¤@¶}©l«ü¥X¤Fperlµ{¦¡ªº©Ò¦b¦a¥H¤Î´X¦æµù¸Ñ¡G
#!/usr/local/bin/perl-w#Åã¥Üĵ§i°T®§
print"MynameisAndyLiu,\n";#Let'sintroduceourselves
print"IliveinTaiwan,\n",
"Iworkinalumbermillthere.\n";#§O§Ñ¤F¥H¤À¸¹³Ì¬°µ²§ô
¸ê®Æµ²ºc¡]DataTypes¡^
Perlªº¸ê®ÆºØÃþ«D±`¦a¤Ö¡C¦pªG§A²ßºDC»y¨¥³oºØ³s¦r¤¸³£¤À¬°unsigned¤Îsigned
¨º§A¨Ï¥ÎPerl±N·|«D±`´r§Ö¡C°ò¥»¤WPerl¥u¦³¨âºØ¸ê®Æµ²ºc¡G
¼ÆÈscalars¥H¤Î°}¦Carrays¡CPerl¦P¼Ë¤]¦³Áp¦X°}¦C
associativearrays³o¬O¤@ºØ¸û¯S®íªº°}¦C¡A´X¥G¥i¦Û¦¨¤@Ãþ¡C
¼ÆÈScalars
©Ò¦³ªº¼Æ¦r¤Î¦r¦ê³£ºÙ¬°¼Æȸê®Æscalars¡C©Ò¦³ªºScalar-variable
«e±³£¦³¤@Ó($).
µù¸Ñ
Perlªº©Ò¦³ÅܼƦWºÙ¡A¥]§t¼Æȸê®Æ³£¦³¤j¤p¼g¤§¤À¡C¤ñ¦p»¡¡G$Name©M$name´N³Qµø¬°§¹¥þ¤£¦PªºªF¦è¡C
Perl·|¦Û¤v±NScalarsÂà´«¦¨¼Æȸê®Æ©Î¬O¼Æ¦r«¬ºA¡C
$a=2;
$b=6;
$c=$a.$b;#"."¹Bºâ¤¸·|±N¨âÓ¦r¦ê³s°_¨Ó¡C
$d=$c/2;
print$d;
°õ¦æªºµ²ªG¬°¡G
13
¤W±³oÓ¨Ò¤l·|±N¨âÓ¾ã¼ÆÂন¦r¦ê¡AµM«á±N¨âÓ¦r¦ê³sµ²¦¨¤@Ó·sªº¦r¦êÅܼơAµM«á
±N·s¦r¦êÂà´«¦¨¾ã¼Æ«¬ºA¡A¦A¥Î2¥h°£¡A¦A±Nµ²ªGÂà´«¦¨¦r¦ê¨Ã¦L¥Xµ²ªG¨ì¿Ã¹õ¤W¡C
ThissituationmightbeaproblemifPerlwereregularlyusedfortasksinwhich
explicitmemoryoffsetswereused,forexample,anddatatypeswerecritical.Butforthe
typeoftaskforwhichPerlisnormallyused-andcertainlyforthetypesoftasksthat
we'llbeusingitforinthisbook-theseautomaticconversionsaresmooth,intuitive,and
generallyaGoodThing.
Wecandeveloptheearlierexamplescriptwithsomestringvariables,asfollows:
#!/usr/local/bin/perl-w#Åã¥Üĵ§i°T®§
$who='YonYonson';
$where='Wisconsin';
$what='inalumbermill';
print"Mynameis$who,\n";#¤¶²Ð¦Û¤v
print"Ilivein$where,\n",
"Iwork$whatthere.\n";
print"\nSigned:\t$who,\n\t\t$where.\n";
°õ¦æ«á¡A·|²£¥Í¤U¦Cµ²ªG¡G
MynameisYonYonson,
IworkinWisconsin,
Iworkinalumbermillthere.
Signed: YonYonson,
Wisconsin.
Don'tworry-itgetsbetter.
°}¦CArrays
¼Æȸê®Æªº¶°¦X§Ú̺٬°°}¦Carray.°}¦CÅܼƷ|¥Î(@)
²Å¸¹§@¬°²Ä¤@Ó¦rªº¶}©l¡C°}¦C¤¤ªº¤¸¯À¤§¶¡·|¥Î³r¸¹¹j¶}¡A´N¹³¤U±Åã¥Üªº¨Ò¤l¤@¼Ë¡G
@trees=("Larch","Hazel","Oak");
°}¦Cªº¤¸¯À¥i¥H¥Î¤¤¬A¸¹¨Óªí¥Ü¡AÁ|¨Ò¨Ó»¡¡G$trees[0]ªí¥Ü³o¬O@trees
°}¦Cªº²Ä¤@Ó¤¸¯À¡Cª`·N¡G³o¸Ì¬O¨Ï¥Î$trees[0]¦Ó¤£¬O@trees[0]
¦]¬°Ó§Oªº¤¸¯À¬O¼Æȸê®Æ¡A©Ò¥H«e±n¥Î$¨Ó¨ú±o¤¸¯ÀªºÈ¡C
Mixingscalartypesinanarrayisnotaproblem.Thecode
@items=(15,'45.67',"case");
print"Take$items[0]$items[2]sat\$$items[1]each.\n";
©³¤U¬O°õ¦æªºµ²ªG¡G
Take15casesat$45.67each.
Perl¸Ì±ªº°}¦C³£¬O°ÊºAªº¡A©p®Ú¥»¤£»Ýn¥h¾á¤ß°O¾ÐÅ骺°t¸m¤ÎºÞ²z¡CPerl·|¬°§A
°µ¦n©Ò¦³ªº¤u§@¡C°}¦C¤§¤¤¤S¥i¥H¥]§t°}¦C¡A©³¤UÁ|Ó¨Ò¤l¨Ó»¡¡G
@A=(1,2,3);
@B=(4,5,6);
@C=(7,8,9);
@D=(@A,@B,@C);
³oÓµ{¦¡°õ¦æªºµ²ªG¡G°}¦C@D¥]§t¤F¸ê®Æ1¨ì9¡C©³¤U¬O§Ú̱`¥Îªº°}¦C¥Îªk¡G
@Annual=(@Spring,@Summer,@Fall,@Winter);
³oÓ½d¨Òµ{¦¡±N¤@¦~¤¤ªº©u¸`¥Î¤@ºØ²¼ä¤Sª½±µ©öÀ´ªº°}¦C¨Óªí¹F¡C¦Ó°}¦C¤¤ªº©u¸`¤S
¥i¥HÂà´«¬°¥]§t¤ë¥÷ªº°}¦C¡A¨CӤ몺°}¦C¤S¥i¥HÂà´«¦¨¬°¥]§t¤Ñ¼Æªº¸ê®Æ¡C
@Annual°}¦C¥i¥HÅܦ¨¥Ñ¤@¦~¤¤ªº¨C¤@¤ÑªºÈ©Ò²Õ¦¨¡C
arraythenwouldconsistofavalueforeachdayoftheyear.Bydefiningyourdatain
chunkssuchasthis,yougiveyourselftheoptionofhandlingitonadaily,monthly,or
annualbasis.
NOTE
AnaspectofPerlthatoftenconfusesnewcomers(andoccasionallyoldhands,too)is
thecontext-sensitivenatureofevaluations.Perlkeepstrackofthecontextinwhichan
expressionisbeingevaluatedandcanreturnadifferentvalueinanarraycontextthanin
ascalarcontext.Inthisexample,thearray@Bcontains1-4,whereas$C
contains4(thenumberofvaluesinthearray):
@A=(1,2,3,4);
@B=@A;
$C=@A;
Thiscontextsensitivitybecomesmoreofanissuewhenyouusefunctionsandoperators
thatcantakeeitherasingleargumentormultiplearguments.Thefunctionorargument
behavesonewaywhenitispassedasinglescalarargumentandanotherwhenitis
passedmultiplearguments,whichitmayinterpretasasinglearrayargument.
ManyofPerl'sbuilt-infunctionstakearraysasarguments.Oneexampleissort,
whichtakesanarrayasanargumentandreturnsthesamearray,sortedalphabetically.The
code
printsort('Beta','Gamma','Alpha');
printsAlphaBetaGamma.
Youcanmakethiscodeneaterbyusinganotherbuilt-infunction,calledjoin.
Thisfunctiontakestwoarguments:astringtoconnectwith,andanarrayofstringsto
connect.joinreturnsasinglestringthatconsistsofallelementsinthearray
joinedwiththeconnectingstring.Thecode
printjoin(':','Name','Address','Phone');
returnsthestringName:Address:Phone.
Becausesortreturnsanarray,youcanfeeditsoutputstraightintojoin.
Thecode
printjoin(',',sort('Beta','Gamma','Alpha'));
printsAlpha,Beta,Gamma.
Noticethatthiscodedoesn'tseparatetheinitialscalarargumentofjoin
fromthearraythatfollowsit.Thefirstargumentisthestringtojointhingswith.The
restoftheargumentsaretreatedasasingleargument:thearraytobejoined.Thisis
trueevenifyouuseparenthesestoseparategroupsofarguments.Thecode
printjoin(':',('A','B','C'),('D','E'),('F','G','H','I'));
returnsA:B:C:D:E:F:G:H:I.
Youcanuseonearrayormultiplearraysinacontextsuchasthisbecauseoftheway
thatPerltreatsarrays;addinganarraytoanarraygivesyouonelargerarray,nottwo
arrays.Inthiscase,allthreearraysarebundledintoone.
TIP
Forevenmorepowerfulstring-manipulationcapabilities,refertothesplice
functioninChapter15,"FunctionList."
²Õ¦X°}¦CAssociativeArrays
AssociativearrayshaveacertainelegancethatmakesexperiencedPerlprogrammersa
littlesnobbishabouttheirlanguageofchoice.Rightlyso!AssociativearraysgivePerla
degreeofdatabasefunctionalityataverylow,yetuseful,level.Manytasksthatwould
otherwiseinvolvecomplexprogrammingcanbereducedtoahandfulofPerlstatementsby
meansofassociativearrays.
Arraysofthetypethatyou'vealreadyseenarelistsofvaluesindexedby
subscripts.Inotherwords,togetanindividualelementofanarray,yousupplya
subscriptasareference,asfollows:
@fruit=("Apple","Orange","Banana");
print$fruit[2];
ThisexampleyieldsBanana,becausesubscriptsstartatzero,so2is
[email protected]$fruit[7]
herereturnsthenullvalue,becausenoarrayelementwiththatsubscripthasbeen
defined.
Now,here'sthepointofallthis:Associativearraysarelistsofvaluesindexedby
strings.Conceptually,that'sallthereistothem.Theimplementationofassociative
arraysismorecomplex,becauseallthestrings(keys)needtobestoredin
additiontothevaluestowhichtheyrefer.
Whenyouwanttorefertoanelementofanassociativearray,yousupplyastring(the
key)insteadofaninteger(thesubscript).Perlreturnsthecorrespondingvalue.Consider
thefollowingexample:
%fruit=("Green","Apple","Orange","Orange","Yellow","Banana");
print$fruit{"Yellow"};
ThiscodeprintsBanana,asbefore.Thefirstlinedefinestheassociative
arrayinmuchthesamewaythatyouhavealreadydefinedordinaryarrays;thedifference
isthatinsteadoflistingvalues,youlistkey/valuepairs.ThefirstvalueisApple,
anditskeyisGreen.ThesecondvalueisOrange,whichhappenstohave
thesamestringforbothvalueandkey.Finally,thevalueBananahasthekeyYellow.
Onasuperficiallevel,youcanusestringsubscriptstoprovidemnemonicsforarray
references,allowingyoutoreferto$Total{'June'}insteadof$Total[5].
Butyouwouldn'tevenbebeginningtousethepowerofassociativearrays.Thinkofthe
keysofanassociativearraysasyoumightthinkofakeythatlinkstablesina
relationaldatabase,andyou'reclosertotheidea.Considerthisexample:
%Folk=('YY','YonYonson',
'TC','TerraCotta',
'RE','RonEverly');
%State=('YY','Wisconsin',
'TC','Minnesota',
'RE','Bliss');
%Job=('YY','workinalumbermill',
'TC','teachnuclearphysics',
'RE','watchfootball');
foreach$person('TC','YY','RE'){
print"Mynameis$Folk{$person},\n",
"Ilivein$State{$person},\n",
"I$Job{$person}there.\n\n";
}
³oÓ¨Ò¤l¸Ì¡A§ÚÌ°½°½ªº¨Ï¥Î¤Fforeach³oÓµ²ºc¦¡¡C³oÓµ²ºc¦¡¦b¥»³¹µy
«áªº¬yµ{±±¨î³¡¤À·|¦A¸Ô²Óªº¸ÑÄÀ¡CFornow,you'lljusthavetotakeitontrustthatforeachmakesPerlexecutethethreeprint
statementsforeachofthepeopleinthelistaftertheforeachkeyword.
Otherwise,youcouldtryexecutingthecodeinthesampleandseewhathappens.
Youalsocantreatthekeysandvaluesofanassociativearrayasseparate(ordinary)
arraysbyusingthekeysandvalueskeywords,respectively.Thecode
printkeys%Folk;
printvalues%State;
printsthestringYYRETCWisconsinBlissMinnesota.
Looksasthoughweneedtodosomemoreworkonstringhandling.Thattaskisbestleft
untilafterwecoversomeflow-controlmechanisms,however.
NOTE
Aspecialassociativearraycalled%ENVstoresthecontentsofallenvironment
variables,indexedbyvariablename.$ENV{'PATH'},forexample,returnsthe
currentsearchpath.Followingisawaytoprintthecurrentvaluesofallenvironment
variables,sortedbyvariablenameforgoodmeasure:
foreach$var(sortkeys%ENV){
print"$var:\"$ENV{$var}\".\n";
}
Theforeachclausesets$vartoeachoftheenvironment-variable
namesinturn(inalphabeticalorder),andtheprintstatementprintseachname
andvalue.Thebackslash-quote(\")inthereproducesquotation
marksaroundthevalues.
FileHandles
ThischapterfinishesdiscussingPerldatatypesbydiscussingfilehandles.Afile
handleisnotreallyadatatypeatall,butaspecialkindofliteralstring.Afile
handlebehaveslikeavariableinmanyways,however,sothissectionisagoodplaceto
coverthem.(Besides,youwon'tgetveryfarinPerlwithoutthem.)
YoucanregardafilehandleasbeingapointertoafilefromwhichPerlistoreador
towhichitwillwrite.(Cprogrammersarefamiliarwiththeconcept.)Thebasicideais
thatyouassociateahandlewithafileordevice,andthenrefertothehandleinthe
codewheneveryouneedtoperformareadorwriteoperation.
Filehandlesgenerallyarewritteninuppercase.Perlhassomeusefulpredefinedfile
handles,asTable1.2shows.
Table1.2 Perl'sPredefinedFileHandles
FileHandle
Pointsto¡K
STDIN
Standardinput(normally,thekeyboard)
STDOUT
Standardoutput(normally,theconsole;inmanyWebapplications,the
browser)
STDERR
Devicewhereerrormessagesshouldbewritten(normally,theconsole;ina
Webserverenvironment,normally,theserver-errorlogfile)
Theprintstatementcantakeafilehandleasitsfirstargument,asfollows:
printSTDERR"Oops,somethingbroke.\n";
Noticethatnocommaappearsafterthefilehandleinthisexample.ThathelpsPerl
figureoutthattheSTDERRisnotsomethingtobeprinted.Ifyou'reuneasywith
thisimplicitlistsyntax,youcanputparenthesesaroundalltheprint
arguments,asfollows:
print(STDERR"Oops,somethingbroke.\n");
Youstillhavenocommaafterthefilehandle,however.
TIP
Usethestandardfilehandlesexplicitly,especiallyincomplexprograms.Redefining
thestandardinputoroutputdeviceforawhileisconvenientsometimes;makesurethat
youdon'taccidentallywindupwritingtoafilewhatshouldhavegonetothescreen.
Youcanusetheopenfunctiontoassociateanewfilehandlewithafile,as
follows:
open(INDATA,"/etc/stuff/Friday.dat");
open(LOGFILE,">/etc/logs/reclaim.log");
printLOGFILE"Logofreclaimprocedure\n";
Bydefault,openopensfilesforreadingonly.Ifyouwanttooverridethis
defaultbehavior,addtothefilenameoneofthespecialdirectionsymbolslistedin
Table1.3.(The>atthestartofthefilenameinthesecondoutput
statementoftheprecedingexample,forexample,tellsPerlthatyouintendtowriteto
thenamedfile.)
Table1.3 PerlFile-AccessSymbols
Symbol
Meaning
<
Openthefileforreading(thedefaultaction)
>
Openthefileforwriting
>>
Openthefileforappending
+<
Openthefileforbothreadingandwriting
+>
Openthefileforbothreadingandwriting
|(beforefilename)
TreatfileascommandintowhichPerlistopipetext
|(afterfilename)
TreatfileascommandfromwhichinputistobepipedtoPerl
Totakeamorecomplexexample,here'sonewaytofeedoutputtothemypr
printeronaUNIXsystem:
open(MYLPR,"|lpr-Pmypr");
printMYLPR"Alineofoutput\n";
closeMYLPR;
AspecialPerloperatorforreadingfromfilesconsistsoftwoangle
brackets-<>-aroundthefilehandleofthefilefromwhichyouwanttoread.This
operatorreturnsthenextlineorlinesofinputfromthefileordevice,dependingon
whethertheoperatorisusedinascalaroranarraycontext.Whennomoreinputremains,
theoperatorreturnsfalse.
Aconstructsuchas
while(){
print;
}
simplyechoeseachlineofinputbacktotheconsoleuntilCtrl+D(Ctrl+ZinWindows
NT)ispressed,becausetheprintfunctiontakesthecurrentdefaultargument
here:themostrecentlineofinput.Foranexplanation,see"SpecialVariables"
laterinthischapter.
Iftheusertypes
A
Bb
Ccc
^D
thescreenlookslikethis:
A
A
Bb
Bb
Ccc
Ccc
^D
Noticethatinthiscase,isinascalarcontext,soonelineof
standardinputisreturnedatatime.Comparethatexamplewiththefollowingexample:
print;
Inthiscase,becauseprintexpectsanarrayofarguments(itcanbea
single-elementarray,butit'sanarrayasfarasprintisconcerned),the<>
operatorobliginglyreturnsallthecontentsofSTDINasanarray,andthenprint
printsit.Becausethearrayisfullybuiltbeforeitisprinted,nothingiswrittento
theconsoleuntiltheuserpressesCtrl+D:
A
Bb
Ccc
^D
A
Bb
Ccc
Thisscriptprintsoutthecontentsofthefile.SIGNATURE,double-spaced:
open(SIGFILE,".signature");
while(){
print;print"\n";
}
Thefirstprintherehasnoarguments,soittakesthecurrentdefault
argumentandprintsit.Thesecondprinthasanargument,soitprintsthat
instead.Perl'shabitofusingdefaultargumentsextendstothe<>
operator;ifthatoperatorisusedwithnofilehandle,Perlassumesthat
isintended.expandstoeachlineinturnofeachfilelistedinthe
commandline.
Ifnofilesarelistedinthecommandline,PerlinsteadassumesthatSTDINis
intended.Thefollowingcode,therefore,keepsprintingmoreaslongassomething
otherthanCtrl+Dappearsinstandardinput:
while(<>){
print"more....";
}
NOTE
Perl5allowsarrayelementstobereferencestoanydatatype.Asaresult,youcan
buildarbitrarydatastructuresofthekindusedinCandotherhigh-levellanguages,but
withallthepowerofPerl.Youcanhaveanarrayofassociativearrays,forexample.
SpecialVariables
Likealllanguages,Perlhasitsspecialhieroglyphs,whichareladenwithmeaning.
Thissectionbrieflyexaminessomeofthemostcommonandusefulvariables,andprovides
someexamplesoftypicalPerlidiomsinwhichyoumightfindthem.
EnvironmentVariables
Youhavealreadyseenonespecialvariable:theenvironment-variableassociativearray%ENV.
Thisspecialassociativearrayallowsyoutoeasilyusethevalueofanyenvironment
variablewithinyourPerlscripts:
print"Lookingforfilesalongthepath($ENV{'PATH'})\n";
The%ENVarrayisquiteusefulinCGIprogramming,inwhichparametersare
passedfromthebrowsertoCGIprogramsasenvironmentsettings.
ProgramArguments
AnyargumentsspecifiedinthePerlcommandlinearepassedtothePerlscriptin
anotherspecialarray:@ARGV.
CAUTION
Cprogrammers,beware:Thefirstelementofthisarrayisthefirstactualargument,
notthenameoftheprogram.Thespecialvariable$0containsthenameofthe
Perlscriptthatisbeingexecuted.
Thefollowingcodeprintsthecommand-lineargumentsoneperline,sorted
alphabetically:
printjoin("\n",sort@ARGV);
Thecommand-lineargumentsareoflimiteduseinCGIscripts,inwhichargumentsare
passedviatheenvironmentratherthanthecommandline.Theseargumentsarequiteuseful
innormalPerlwork,ofcourse.
CurrentLine
Thespecialvariable$_isoftenusedtostorethecurrentlineofinput.This
situationistruewhenthe<>inputoperatorisused.Thefollowingcode,
forexample,printsanumberedlistingofthefilepointedtobySOMEFILE:
$line=0;
while(){
++$line;
print"Line$line:",$_;
}
Youoccasionallyneedtostorethecontentsof$_somewhere,asinthe
followingexample:
$oldvalue=$_;
Buttheoppositeoperation-settingthevalueof$_manually-israrely
appropriate,asinthisexample:
$_=$oldvalue;
Patternmatchingandsubstitutiontakeplaceonthecontentsofthisvariableunless
youspecifyotherwise.Thesetopicsarecoveredin"RegularExpressions"later
inthischapter.
SystemErrorMessages
Thespecialvariable$!containsthecurrentsystem-errornumber(errno,
onUNIXsystems)orsystem-errorstring,dependingonwhetheritisevaluatedinanumeric
orstringcontext.Thisvariablemaynotcontainanythingmeaningful;itshouldbeused
onlyifanerroroccurred.
Thisexamplereportsfailureiftheopencallfailed:
open(INFILE,"./missing.txt")||die"Couldn'topen\"./missing.txt\"($!).\n";
The||hereistheBooleanoroperator,whichiscoveredin
"FlowControl"laterinthischapter.diecausesPerltoterminate
afterprintingthestringgiventodieasanargument.
Ifthefiledoesnotexist,Perlterminatesafterdisplayingsomethinglikethis:
Couldn'topen"./missing.txt"(Nosuchfileordirectory).
Theformandcontentoferrormessagesvaryfromonesystemtothenext.
¬yµ{±±¨î
Theexamplesthatyouhaveseensofarhavebeenquitesimple,withlittleornologicalstructurebeyondalinearsequenceofsteps.Wemanagedtosneakintheoccasionalwhileandforeach;thinkofthoseasbeingsneakpreviews.Perlhasalltheflow-controlmechanismsthatyou'dexpecttofindinahigh-levellanguage,andthissectiontakesyouthroughthebasicsofeachmechanism.
ÅÞ¿è¹Bºâ¤¸
Twooperators-||(or)and&&(and)-areusedlikegluetoholdPerlprogramstogether.Theytaketwooperandsandreturneithertrueorfalse,dependingontheoperands.Inthefollowingexample,ifeither$Saturdayor$Sundayistrue,$Weekendwillbetrue,too:
$Weekend=$Saturday||$Sunday;
Inthenextexample,$Solventistrueonlyif$incomeisgreaterthan
3and$debtsislessthan10:
$Solvent=($income>3)&&($debts<10);
Nowconsiderthelogicofevaluatingoneoftheseexpressions.Itisn'talways
necessarytoevaluatebothoperandsofeitheran&&ora||
operator.Inthefirstexampleearlierinthissection,if$Saturdayistrue,you
knowthat$Weekendwillbetrue,regardlessofwhether$Sundayisalso
true(themidnightcondition,perhaps?).
Thismeansthatwhentheleftsideofanorexpressionisevaluatedastrue,
therightsideisnotevaluated.CombinethiswithPerl'seasywaywithdatatypes,and
youcansaythingslikethefollowing:
$value>10||print"Oops,lowvalue\n";
If$valueisgreaterthan10,therightsideoftheexpressionisnever
evaluated,sonothingisprinted.If$valueisnotgreaterthan10,Perl
needstoevaluatetherightside,too,soastodecidewhethertheexpressionasawhole
istrueorfalse.ThatmeansthatPerlevaluatestheprintstatement,printing
outthemessage.
OK,it'satrick,butit'saveryusefulone.
Somethinganalogousappliestothe&&operator.Inthiscase,ifthe
leftsideofanexpressionisfalse,theexpressionasawholeisfalse,soPerldoesnot
evaluatetherightside.The&&operatorcan,therefore,beusedto
producethesamekindofeffectasthe||trick,butwiththeoppositesense,as
inthefollowingexample:
$value>10&&print"OK,valueishighenough\n";
AsistrueofmostPerlconstructs,therealpowerofthesetrickscomeswhenyouapply
alittlecreativethinking.Rememberthattheleftandrightsidesoftheseexpressions
canbeanyPerlexpressions;thinkofthemasbeingconjunctionsinasentenceratherthan
logicaloperators,andyou'llgetabetterfeelforhowtousethem.Expressionssuchas
thefollowinggiveyoualittleoftheflavorofcreativePerl:
$length<=80||die"Linetoolong.\n";
$errorlevel>3&&warn"Hmmm,strangeerrorlevel($errorlevel)\n";
open(LOGFILE,">install.log")||&bust("Logfile");
The&bustinthisexampleisasubroutinecall,bytheway.Referto
"Subroutines"laterinthischapterformoreinformation.
ConditionalExpressions
Themostbasickindofflowcontrolisasimplebranch.Astatementiseitherexecuted
ornot,dependingonwhetheralogicalexpressionistrueorfalse.Youcandothisby
followingthestatementwithamodifierandalogicalexpression,asfollows:
open(INFILE,"./missing.txt")if$missing;
Theexecutionofthestatementiscontingentuponboththeevaluationofthe
expressionandthesenseoftheoperator.
Theexpressionisevaluatedaseithertrueorfalseandcancontainanyofthe
relationaloperatorslistedinTable1.4(althoughitneednot).Followingareafew
examplesofvalidexpressions:
$full
$a==$b
Table1.4 Perl'sRelationalOperators
Operator
NumericContext
StringContext
Equality
==
eq
Inequality
!=
ne
Inequalitywithsignedresult
<=>
cmp
Greaterthan
>
gt
Greaterthanorequalto
>=
ge
Lessthan
<
lt
Lessthanorequalto
<=
le
NOTE
Whenwe'recomparingstrings,lessthanmeanslexicallylessthan.If$left
comesbefore$rightwhenthetwoaresortedalphabetically,$leftis
lessthan$right.
Perlhasfourmodifiers,eachofwhichbehavesthewaythatyoumightexpectfromthe
correspondingEnglishword:
if.Thestatementisexecutedifthelogicalexpressionistrueandisnot
executedotherwise.Examples:
$max=100if$min<100;
print"Empty!\n"if!$full;
unless.Thestatementisnotexecutedifthelogicalexpressionistrueandis
executedotherwise.Examples:
open(ERRLOG,"test.log")unless$NoLog;
print"Success"unless$error>2;
while.Thestatementisexecutedrepeatedlyuntilthelogicalexpressionis
false.Examples:
$total-=$decrementwhile$total>$decrement;
$n=1000;"print$n\n"while$n->0;
until.Thestatementisexecutedrepeatedlyuntilthelogicalexpressionis
true.Examples:
$total+=$value[$count++]until$total>$limit;
printRESULTS"Nextvalue:$value[$n++]"until$value[$n]=-1;
Noticethatthelogicalexpressionisevaluatedonlyonetimeinthecaseofif
andunless,butmultipletimesinthecaseofwhileanduntil.
Inotherwords,thefirsttwoaresimpleconditionals,andthelasttwoareloop
constructs.
CompoundStatements
Thesyntaxchangeswhenyouwanttomaketheexecutionofmultiplestatements
contingentontheevaluationofalogicalexpression.Themodifiercomesatthestartofa
line,followedbythelogicalexpressioninparentheses,followedbytheconditional
statementsinbraces.Noticethattheparenthesesaroundthelogicalexpressionare
required,althoughtheyarenotrequiredinthesinglestatementbranchingdescribedin
theprecedingsection.
ThefollowingexampleissomewhatsimilartoC'sifsyntax:
if(($total+=$value)>$limit){
printLOGFILE"Maximumlimit$limitexceeded.Offendingvaluewas$value.\n";
close(LOGFILE);
die"Toomany!Checkthelogfilefordetails.\n";
}
Theifstatementiscapableofalittlemorecomplexity,withelse
andelsifoperators,asinthefollowingexample:
if(!open(LOGFILE,"install.log")){
close(INFILE);
die"Unabletoopenlogfile!\n";
}
elsif(!open(CFGFILE,">system.cfg")){
printLOGFILE"Errorduringinstall:Unabletoopenconfigfileforwriting.\n";
close(LOGFILE);
die"Unabletoopenconfigfileforwriting!\n";
}
else{
printCFGFILE"Yoursettingsgohere!\n";
}
Loops
Theloopmodifiers(while,until,for,andforeach)areusedwithcompoundstatementsinmuchthesameway,asthefollowingexampleshows:
until($total>=50){
print"Enteravalue:";
$value=scalar();
$total+=$value;
print"Currenttotalis$total\n";
}
print"Enough!\n";
Thewhileanduntilstatementsaredescribedin"ConditionalExpressions"earlierinthischapter.TheforstatementresemblestheoneinC.forisfollowedbyaninitialvalue,aterminationcondition,andaniterationexpression,allenclosedinparenthesesandseparatedbysemicolons,asfollows:
for($count=0;$count<100;$count++){
print"Something";
}
Theforeachoperatorisspecial;ititeratesoverthecontentsofanarrayandexecutesthestatementsinastatementblockforeachelementofthearray.Followingisasimpleexample:
@numbers=("one","two","three","four");
foreach$num(@numbers){
print"Number$num\n";
}
Thevariable$numfirsttakesonthevalueone,thentwo,andsoon.Thatexamplelooksfairlytrivial,buttherealpowerofthisoperatorliesinthefactthatitcanoperateonanyarray,asfollows:
foreach$arg(@ARGV){
print"Argument:\"$arg\".\n";
}
foreach$namekey(sortkeys%surnames){
printREPORT"Surname:$value{$namekey}.\n",
"Address:$address{$namekey}.\n";
}
Labels
Youcanuselabelswiththenext,last,andredostatementstoprovidemorecontrolofprogramflowthroughloops.Alabelconsistsofanyword,usuallyinuppercase,followedbyacolon.Thelabelappearsjustbeforetheloopoperator(while,for,orforeach)andcanbeusedasananchorforjumpingtofromwithintheblock.Thefollowingcodesnippetprintsalltheodd-numberedrecordsinINFILE:
RECORD:while(){
$even=!$even;
nextRECORDif$even;
print;
}
Thethreelabel-controlstatementsare:
next.Jumpstothenextiterationoftheloopmarkedbythelabelortothe
innermostenclosingloop,ifnolabelisspecified.
last.Immediatelybreaksoutoftheloopmarkedbythelabeloroutofthe
innermostenclosingloop,ifnolabelisspecified.
redo.Jumpsbacktotheloopmarkedbythespecifiedlabelortotheinnermost
enclosingloop,ifnolabelisspecified.redocausesthelooptoexecuteagain
withthesameiteratorvalue.
Subroutines
SubroutinesinPerlaredefinedwiththesubkeyword,asfollows:
subUsage{
print"Usage:\n",
"twiddle[-args]infileoutfile\n";
print"Copyleft1996,JonathanF.Squirmsby.";
}
Subroutinesarecalledwith&,asfollows:
subbust{
print"Oops,somekindoferrorseemstohaveoccurred.\n";
die"Fatalerror,terminating.\n";
}
open(LOGFILE,">install.log")||&bust;
Inthisexample,thesubroutinewasdefinedbeforeitwascalled.Youcandefineand
callsubroutinesinanyorderinPerl;theconventionistodefinethemafterthemain
routine.
PassingArguments Youcanpassargumentstoasubroutineintheusual
way,asfollows:
open(LOGFILE,">install.log")||&bust("Failedtoopenlogfile\"install.log\".");
ButhereiswherePerl'ssubroutinesyntaxstartstogetalittlestrange;C
programmersmaywanttotakeaseatbeforereadingon.
AllPerlsubroutinesreceivetheirargumentsasanarbitrarilylongarrayofscalars
withthespecialnameof@_.Thereisnomechanismfordeclaringthearguments
whenthesubroutineisdeclared.Thereisnofixednumberofarguments.Also,thecalling
functioncanpassanymixtureofscalarsandarrays;theyarealltreatedasonebig@_
arraywhentheygettothesubroutine.
Intheexampleearlierinthissection,inwhichbustiscalledwithasingle
argument,youcanpickitupinthesubroutineanduseittoprovideamoresensibleerror
message,asinthefollowingexample:
subbust{
($errortext)=@_;
print"Oops,anerroroccurred($errortext).\n";
die"Fatalerror,terminating.\n";
}
Noticethatwewenttothetroubleofassigningthescalar$errortexttothe
argumentarray@_.Thisassignmentmayseemtobeunnecessary;infact,wecould
havesimplyused@_insteadof$errortextintheprint
statement.Explicitlyassigningvariablestothecontentsofthe@_arrayismuch
clearer,though,especiallywhenthesubroutinetakesmultiplearguments.Comparethe
example
print"Error$_[0]openingfile$_[1].\n";
withthisone:
($errfile,$errtext)=@_;
print"Error$errtextopeningfile$errfile.\n";
Notice,too,thatwhenweassignedthesinglevalue$errortexttothe@_
arrayinthebustexample,weplaceditinparentheses.Wedidsotoforcean
arraycontext,sothatwhatgetsassignedto$errortextisthefirst(andonly)
valueofthe@_array,notthenumberofvaluesin@_.Ineffect,we're
tellingPerltotreat$errortextasasingle-elementarray.Theearlierexample
thatuses$errfileand$errtextisaclearerexampleofan
array-to-arrayassignment.
In"VariableScope"laterinthischapter,youlearnhowtoprotectlocal
variablessuchas$errortextinsubroutinesbyusingthelocalandmy
keywords.
PassingArrays Perl'sgroupingofallsubroutineargumentsmakesit
impossibletopassmorethanonearraytoaPerlsubroutine.Supposethatyouhavea
subroutinecallofthefollowingform:
&PrintRes("alpha",(1,3,5,7),"beta",(2,4,6,8));
Trytounpacktheseargumentsintothefollowingvaluesastheycomeintothe
subroutine:
$p1="alpha";
@p2=(1,3,5,7);
$p3="beta";
@p4=(2,4,6,8);
Astatementlike
($p1,@p2,$p3,@p4)=@_;
won'tgetbeyondthesecondparameter.Thefollowinglistexplainswhathappens:
Thefirstvariableinthelist,$p1,isassignedthevalueofthefirstscalar
inthe@_argumentarray,whichisalpha.
Thenthenextvariableinthelist,@p2,isassignedthevalueofthenext
argumentinthe@_argumentarray.Thisisanarrayassignmentbecause@p2
isanarray,sotheentire@_array,fromitssecondelementon,isassignedto@p2-(1,
3,5,7,"beta",2,4,6,8),inotherwords.
Thenextvariabletobeassignedis$p3.Thisvariableisassignedthevalueof
thenextelementinthe@_argumentarray-buttherearen'tanyleft,because
they'veallbeenslurpedby@p2.$p3,therefore,isnull.
Thefinalvariable,@p4,suffersthesamefateandisalsonull.
There'snopointintryingtospecifysubarrays,asinthefollowingexample,because
Perlexpandsthearrayonthelefttothesamethingasbefore:
($p1,(@p2),$p3,(@p4))=@_;
Themoralofthestoryis:Don'tpassmorethanonearrayintoasubroutine.Andifyou
dopassanarray,makesurethatit'sthelastargument.
ReturningValues Perlisjustascasualaboutreturningvaluesfrom
subroutinesasitisaboutpassingargumentstothem.Asubroutinereturnsasinglevalue:
thevalueofthelastassign-mentmadeinthesubroutine.Ifyoupass(4,3)
tothissubroutine,thevalue7isreturned:
subAddIt{
($a,$b)=@_;
$a+$b;
}
Thatmeansthatthevalue7issubstitutedforthesubroutinecallafter
evaluation.Thecode
print"Summing4and3yields",&AddIt(4,3),".\n";
printsthefollowing:
Summing4and3yields7.
NoticethatwehadtokeepthesubroutinecalloutsidethequotestoallowPerlto
recognize&asasubroutineinvocation.
Itisn'talwaysclearwhichstatementisthelasttobeexecutedinasubroutine,
particularlyifitcontainsloopsorconditionalstatements.Onewaytoensurethatthe
correctvalueisreturnedistoplaceareferencetothevariableonalinebyitselfat
theendofthesubroutine,asfollows:
subMaybe{
#Variousloopsandconditionalsherewhichsetthevalueof"$result"
$result;
}
CAUTION
Takecarenottoaddseeminglyinnocuousstatementsneartheendofasubroutine.Aprint
statementreturnsavalueof1(ifsuccessful)forexample,soasubroutinethatprints
somethingjustbeforeitreturnsalwaysreturns1.
Thereturnvaluecanbeascalar,anarray,oranassociativearray.Listing1.1shows
acompleteexampleinwhichasubroutinebuildsanassociativearrayofnameskeyedby
initialsandthenreturnstheassociativearray.Thekeysofthisarray-theinitials-are
thenprintedinsortedorder.Takeyourtimereadingthroughthisexample;alotisgoing
oninthere,butit'scomprehensivelycommented.
Listing1.1 INITIALS.PL:ReturninganAssociativeArrayfromaSubroutine
#!/usr/local/bin/perl-w
#Passthenamesintothesubroutine.
#Storetheresultsinanassociativearraycalled"keyedNames".
%keyedNames=&GetInitials("JaneAusten","EmilyBronte","MaryShelley");
#Printouttheinitials,sorted:
print"Initialsare",join(',',sortkeys%keyedNames),".\n";
#TheGetInitialssubroutine.
subGetInitials{
#Let'sstoretheargumentsina"names"arrayforclarity.
@names=@_;
#Processeachnameinturn:
foreach$name(@names){
#The"split"functionisexplainedinChapter15,"FunctionList".
#Inthisstatement,we'regettingsplittolookforthe''inthename;
#Itreturnsanarrayofchunksoftheoriginalstring(i.e.$name)whichwere
#separatedbyspaces,i.e.theforenameandsurnamerespectivelyinourcase.
#Thevariables"$forename"and"$surname"arethenassignedtothisarray
#usingparenthesestoforceanarrayassignment.
($forename,$surname)=split('',$name);
#OK,nowwehavetheforenameandsurname.Weusethe"substr"function,
#alsoexplainedinchapter15,toextractthefirstcharacterfromeach
ofthese.
#The"."operatorconcatenatestwostrings(forexample,"aa"."bb"is"aabb")
#sothevariable"$inits"takesonthevalueoftheinitialsofthename:
$inits=substr($forename,0,1).substr($surname,0,1);
#Nowwestorethenameinanassociativearrayusingtheinitialsasthekey:
$NamesByInitials{$inits}=$name;
}
#Havingbuilttheassociativearray,wesimplyrefertoitattheendofthe
#subroutinesothatit'svalueisthelastthingevaluatedhere.Itwillthen
#bepassedbacktothecallingfunction.
%NamesByInitials;
}
VariableScope
Perlusesseparatenamespacestostorescalars,arrays,associativearrays,andsoon.
Asaresult,youcanusethesamenameforvariablesofdifferenttypeswithoutfearof
confusion(atleastonPerl'spart;foryourownsake,useuniquenames).This
exampleusesthreedifferentkindsofvariables,eachcalledname:
$name="Dana";
@name=("Donna","Dana","Diana");
%name=("Donna","Elephants","Dana","Finches","Diana","Parakeets");
print"Isaid$name{$name},not$name{$name[0]}!\n";
Thebadnewsisthatbydefault,Perlusesjustonenamespaceforeachdatatype,for
allfunctions.Soifyouhaveavariablecalled$tempinthemainfunction,and
youcallaroutinethatusesanothervariablecalled$temp,thevalueof$temp
inthemainfunctiongetsclobbered.Thereferencestothetwovariablesareinfacttwo
referencestothesamevariable,asfarasPerlisconcerned.
That'swherethelocal(Perl4and5)andmy(Perl5only)functions
comein.ThesefunctionsforcePerltotreatvariablesasthoughtheyarelocaltothe
currentcodeblock,whetherthatblockisaloop,anif-block,orasubroutine.
Thefollowingexampleusestwovariablescalled$temp(oneoutsideandone
insideawhileloop):
$temp="Stillhere!\n";
print"Enterafewwordsatatime,Ctrl+Dtoterminate:\n";
while(<>){
local($temp,@etc)=split('',$_);
print"Yousaid$temp";
@etc&&print"andthenyousaid@etc";
print".Entersomemore,orpressCtrl+Dtoend:\n";
}
print$temp;
ThedifferencebetweenPerl4'slocal()andPerl5'smy()isthatlocal
variablesarelocaltothecurrentpackage,whereasmyvariablesarereally
local.
Patterns
We'llfinishthisoverviewofPerlbydiscussingitspattern-matchingcapabilities.The
capabilitytomatchandreplacepatternsisvitaltoanyscriptinglanguagethatclaimsto
becapableofusefultextmanipulation.Bythisstage,youprobablywon'tbesurprisedto
readthatPerlmatchespatternsbetterthananyothergeneral-purposelanguagedoes.Perl
4'spatternmatchingisexcellent,butPerl5introducessomesignificantimprovements,
includingthecapabilitytomatchonevenmorearbitrarystringsthanbefore.
Thebasicpattern-matchingoperationsdiscussedinthissectionare:
Matching,inwhichwewanttoknowwhetheraparticularstringmatchesapattern
Substitution,inwhichwewanttoreplaceportionsofastringbasedonapattern
Thepatternsreferredtoherearemoreproperlyknownasregularexpressions,andwe'll
startbylookingatthem.
RegularExpressions
Aregularexpressionisasetofrulesthatdescribesageneralizedstring.If
thecharactersthatmakeupaparticularstringconformtotherulesofaparticular
regularexpression,theregularexpressionissaidtomatchthatstring.
Afewconcreteexamplesusuallyhelpafteranoverblowndefinitionlikethatone.The
regularexpressionb.matchesthestringsbovine,above,Bobby,andBobJones,butnotthe
stringsBell,b,orBob.That'sbecausetheexpressioninsiststhattheletterb
(lowercase)mustbeinthestringandmustbefollowedimmediatelybyanothercharacter.
Theregularexpressionb+,ontheotherhand,requiresthelowercaseletterbat
leastonce.ThisexpressionmatchesbandBobinadditiontotheexamplematchesforb.in
theprecedingparagraph.Theregularexpressionb*requireszeroormorebs,soit
matchesanystring.Thatseemstobefairlyuseless,butitmakesmoresenseaspartofa
largerregularexpression.Bob*y,forexample,matchesallofBoy,Boby,andBobbybutnot
Boboby.
Assertions Severalso-calledassertionsareusedtoanchorpartsof
thepatterntowordorstringboundaries.The^assertionmatchesthestartofa
string,sotheregularexpression^foolmatchesfoolandfoolhardybut
nottomfooleryorAprilfool.Table1.5liststheassertions.
Table1.5 Perl'sRegular-ExpressionAssertions
Assertion
Matches
Example
Matches
Doesn'tMatch
^
Startofstring
^fool
foolish
tomfoolery
$
Endofstring
fool$
Aprilfool
foolish
\b
Wordboundary
be\bside
beside
beside
\B
Nonwordboundary
be\Bside
beside
beside
Atoms The.(period)thatyousawinb.earlierinthischapterisan
exampleofaregular-expressionatom.Atomsare,asthenamesuggests,the
fundamentalbuildingblocksofaregularexpression.AfulllistofatomsappearsinTable
1.6.
Table1.6 Perl'sRegular-ExpressionAtoms
Atom
Matches
Example
Matches
Doesn'tMatch
period(.)
Anycharacterexceptnewline
b.b
bob
bb
Listofcharactersinbrackets
Anyoneofthosecharacters
^[Bb]
Bob,bob
Rbob
Regularexpressioninparentheses
Anythingthatregularexpressionmatches
^a(b.b)c$
abobc
abbc
Quantifiers Aquantifierisamodifierforanatom.Itcanbe
usedtospecifythataparticularatommustappearatleastonce,asinb+.Theatom
quantifiersarelistedinTable1.7.
Table1.7 Perl'sRegular-ExpressionAtomQuantifiers
Quantifier
Matches
Example
Matches
Doesn'tMatch
*
Zeroormoreinstancesoftheatom
ab*c
ac,abc
abb
+
Oneormoreinstancesoftheatom
ab+c
abc
ac
?
Zerooroneinstancesoftheatom
ab?c
ac,abc
abbc
{n}
ninstancesoftheatom
ab{2}c
abbc
abbbc
{n,}
Atleastninstancesoftheatom
ab{2,}c
abbc,abbbc
abc
{nm}
Atleastn,mostminstancesoftheatom
ab{2,3}c
abbc
abbbbcat
SpecialCharacters Severalspecialcharactersaredenotedby
backslashedletters,with\nbeingespeciallyfamiliartoCprogrammers,perhaps.
Table1.8liststhespecialcharacters.
Table1.8 Perl'sRegular-ExpressionSpecialCharacters
Symbol
Matches
Example
Matches
Doesn'tMatch
\d
Anydigit
b\dd
b4d
bad
\D
Nondigit
b\Dd
bdd
b4d
\n
Newline
¡@
¡@
\r
Carriagereturn
¡@
¡@
\t
Tab
¡@
¡@
\f
Formfeed
¡@
¡@
\s
White-spacecharacter
¡@
¡@
\S
Non-white-spacecharacter
¡@
¡@
\w
Alphanumericcharacter
a\wb
a2b
a^b
\W
Nonalphanumericcharacter
a\Wb
aa^b
aabb
BackslashedTokens Itisessentialthatregularexpressionsbe
capableofusingallcharacters,sothatallpossiblestringsthatoccurintherealword
canbematched.Withsomanycharactershavingspecialmeanings,amechanismisrequired
thatallowsyoutorepresentanyarbitrarycharacterinaregularexpression.
Thismechanismisabackslash(\),followedbyanumericquantity.This
quantitycantakeanyofthefollowingformats:
Singleordoubledigit:matchedquantitiesafteramatch.Thesematched
quantitiesarecalledbackreferencesandareexplainedinthefollowingsection.
Two-orthree-digitoctalnumber:thecharacterwiththatnumberascharacter
code,unlessit'spossibletointerpretitasabackreference.
x,followedbytwohexadecimaldigits:thecharacterwiththatnumberas
itscharactercode.\x3e,forexample,is>.
c,followedbyasinglecharacter:thecontrolcharacter.\cG,
forexample,matchesCtrl+G.
Anyothercharacter:thecharacteritself.\&,forexample,matches
the&character.
Matching
Nowyou'rereadytostartputtingallthatinformationtogetherwithsomerealpattern
matching.Thematchoperatornormallyconsistsoftwoforwardslasheswitharegular
expressioninbetween,anditnormallyoperatesonthecontentsofthe$_
variable.Soif$_isserendipity,/^ser/,/end/,and/^s.*y$/
arealltrue.
Matchingon$_ The$_operatorisspecial;seeChapter13,"SpecialVariables,"forfulldetails.Inmany
ways,$_isthedefaultcontainerfordatathatisbeingreadinbyPerl.The<>
operator,forexample,getsthenextlinefromSTDINandstoresitin$_.
Sothefollowingcodesnippetallowsyoutotypelinesoftextandtellsyouwhenyour
linematchesoneoftheregularexpressions:
$prompt="EntersometextorpressCtrl+Dtostop:";
print$prompt;
while(<>){
/^[aA]/&&print"StartswithaorA.";
/[0-9]$/&&print"Endswithadigit.";
/perl/&&print"Yousaidit!";
print$prompt;
}
BoundMatches Matchingdoesn'talwayshavetooperateon$_,
althoughthisdefaultbehaviorisquiteconvenient.Aspecialoperator,=~,
evaluatestoeithertrueorfalse,dependingonwhetheritsfirstoperandmatchesonits
secondoperand.So$filename=~/dat$/istrueif$filenamematcheson/dat$/.
Youcanuse=~inconditionalsintheusualway,asfollows:
?$filename=~/dat$/&&die"Can'tuse.datfiles.\n";
Acorrespondingoperator,!~,hastheoppositesense.!~istrueif
thefirstoperatordoesnotmatchonthesecond,asfollows:
$ENV{'PATH'}!~/perl/&&warn"Notsureifperlisinyourpath";
AlternativeDelimiters Thematchoperatorcanusecharactersother
than//-ausefulpointifyou'retryingtomatchacomplexexpressionthat
involvesforwardslashes.Amoregeneralformofthematchoperatorthan//ism//.
Ifyouusetheleadingm,youcanuseanycharactertodelimittheregular
expression.Forexample,
$installpath=~m!^/usr/local!||warn"Thepathyouhavechosenisodd.\n";
warnsthat"Thepathyouhavechosenisodd.\n"ifthevariable$installpath
startswith/usr/local.
MatchOptions Youcanapplyseveraloptionalswitchestothematch
operator(either//orm//)toalteritsbehavior.Theseoptionsare
listedinTable1.9.
Table1.9 Perl'sMatch-OperatorOptionalSwitches
Switch
Meaning
g
Performglobalmatching
i
Performcase-insensitivematching
o
Evaluatetheregularexpressiononetimeonly
Thegswitchcontinuesmatchingevenafterthefirstmatchhasbeenfound.
Thisswitchisusefulwhenyouareusingbackreferencestoexaminethematchedportionsof
astring,asdescribedinthe"Backreferences"sectionlaterinthischapter.
Theiswitchforcesacase-insensitivematch.
Finally,theoswitchisusedinsideloopsinwhichagreatdealofpattern
matchingistakingplace.ThisswitchtellsPerlthattheregularexpression(thematch
operator'soperand)istobeevaluatedonetimeonly.Theswitchcanimproveefficiency
whentheregularexpressionisfixedforalliterationsoftheloopthatcontainsit.
Backreferences Aswementionedinthe"BackslashedTokens"
sectionearlierinthischapter,patternmatchingproducesquantitiesthatareknownasbackreferences.
Thesequantitiesarethepartsofyourstringinwhichthematchsucceeded.Youneedto
tellPerltostorethembysurroundingtherelevantpartsofyourregularexpressionwith
parentheses,andyoucanrefertothemafterthematchas\1,\2,andsoon.The
followingexampledetermineswhethertheusertypedthreeconsecutivefour-letterwords:
while(<>){
/\b(\S{4})\s(\S{4})\s(\S{4})\b/&&print"Gosh,yousaid$1$2$3!\n";
}
Thefirstfour-letterwordliesbetweenawordboundary(\b)andsomewhite
space(\s),andconsistsoffournon-white-spacecharacters(\S).If
thereisamatchontheexpression\b(\S{4})\s-ifafour-letterwordisfound-the
matchingsubstringisstoredinthespecialvariable\1,andthesearch
continues.Whenthesearchiscomplete,youcanrefertothebackreferencesas$1,$2,
andsoon.
Whatifyoudon'tknowinadvancehowmanymatchestoexpect?Performthematchinan
arraycontext;Perlreturnsthematchesinanarray.Considerthisexample:
@hits=("YonYonson,Wisconsin"=~/(\won)/g);
print"Matchedon",join(',',@hits),".\n";
We'llstartattherightsideandworkbackward.Theregularexpression(\won)
meansthatwematchanyalphanumericcharacterfollowedbyonandstoreallthree
characters.Thegoptionafterthe//operatormeansthatwewanttodo
thisfortheentirestring,evenafterwefindamatch.The=~operatormeans
thatwecarryoutthisoperationonagivenstring(YonYonson,Wisconsin).
Finally,thewholethingisevaluatedinanarraycontext,soPerlreturnsthearrayof
matches,[email protected]:
MatchedonYon,Yon,son,con.
Substitution
Whenyougetthehangofpatternmatching,you'llfindthatsubstitutionsarequite
straightforwardandverypowerful.Thesubstitutionoperatoriss///,which
resemblesthematchoperatorbuthasthreeratherthantwoslashes.Justasyoucando
withthematchoperator,youcansubstituteanyothercharacterfortheforwardslashes,
andyoucanusetheoptionali,g,andoswitches.
Thepatterntobereplacedgoesbetweenthefirstandseconddelimiters,andthe
replacementpatterngoesbetweenthesecondandthirddelimiters.Thissimpleexample
changes$housefromhenhousetodoghouse:
$house="henhouse";
$house=~s/hen/dog/;
Noticethatitisn'tpossibletousethe=~operatorwithaliteral
stringasyoucanwhenmatching,becauseyoucan'tmodifyaliteralconstant.Instead,
storethestringinavariableandmodifythatvariable.
FromHere...
YouhavereachedtheendofyourwhirlwindtourofPerl.YousawhowPerl'sdeceptively
simpleconstructscanbeusedtowritedeceptivelysimpleprograms,andyougotabrief
lookatthebasicelementsofthelanguage.Atminimum,youshouldhaveaclearideaof
howthelanguageworks,andyoushouldknowwheretogoformoreinformationonPerlas
theneedarisesthroughouttherestofthisbook.
ThisbooknowmovesontoWebmatters,butlookinthefollowingplacesformore
informationaboutPerl:
RefertoPartVofthisbookforcomprehensiveinformationonPerlspecialvariables,
operators,andbuilt-infunctions.
AlsorefertoPartVtolearnhowtousemodulesandlibrariestocompartmentalizeyour
codeforgreaterrobustnessandextensibility.
ConsiderbuyingabookthatdealsindetailwiththePerllanguage.Thedefinitivework
isthe"Camelbook,"citedatthebeginningofthischapter.
¡@