Perl Sthomasdotnet- lokesh B

Embed Size (px)

Citation preview

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    1/118

    What you need to know

    You need to be able to differentiate between a PC and a toaster. No programming experience isnecessary. You do need to understand the basics of PC operation. If you don't understand whatdirectories and files are then you'll find this difficult. You might find it difficult even if you do :-)

    You do need to exercise the brain cells, and you need time.

    What you need to have

    A PC which can run a Win32 operating system. That's Windows NT 3.5, 3.51, 4.0 or later, orWindows 95 or Windows 98. Not Windows 3.1. Sorry. Now, you finally have a reason toupgrade.

    You need to get hold of a copy of Perl, so for that you might need an Internet connection. Butif you can get it some other way, you don't.

    Note: You don't even need a Win32 PC if you are comfortable installing Perl under other operatingsystems like Linux, but not all the information here will be relevant.

    You don't need a complier. Perl is an interpreted language, which means you run code directly, notcompile it then run it.

    How to use this tutorial...

    Just work through from start to finish.

    Generally, the explanation follows the code sample. Before you read the explanation, try and workout what the code does. Then check if you're right. In this way, you'll derive maximum value from thetutorial and exercise the old grey cells a little.

    When you finish, please send me a critique. In fact, send one even if you don't finish. Iappreciate allfeedback! Please note -- I am not a source of free technical support. Do not email meyour general Perl problems. If you want support, ask on Usenet or the ActiveState mailing lists. Thatsaid, I welcome problems related to the tutorial itself.

    Conventions used in this TutorialThe humour is non-conventional. I think. Of more importance, the text is coloured strangely inplaces. My intention is to aid your comprehension, not attempt beautification. The meaning of thecolours:

    Sometimes you'll need to type something in on the command line. These commands will bein green, for example :perl changeworld.pl parm1 datafile.txt

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    2/118

    Code that you should load into your editor and run is in blue (don't run this now, it's just anexample):

    while () {

    printf "%2s : $_",$.;

    }

    when functions are referred to in the text, their names are highlighted in red. For example,later we discover an interesting function called split.

    All the code examples have been tested, and you can just cut'n'paste (brave statement). I haven'tlisted the output of each example. You need to run it and see for yourself. Consider this courseinteractive. Consider it any which way you like.

    Use of this document

    Personal Printouts

    Fine by me, feel free print to a copy for your own use.

    Intranet usage

    Just email me and let me know.

    Mirroring

    Again, all I ask is an email.

    Translations

    Every so often someone offers to translate the tutorial. Nobody has actually done so. If you want to,the conditions are:

    You don't change the text other than what can be reasonably expected during a translation; The content, format and notices authorship remains the same; You can add a 'translated by' notice in the intro and at the end, plus your own message; Version numbers are respected but the ISO code for your country is added, eg 3.3.2.ES; and you need to email me to discuss.

    Remember this document is copyrighted and all associated rights are strictly reserved.

    --

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    3/118

    Robert Peppermailto:[email protected]

    A Short Introduction To PerlIf you already understand what Perl is designed to do, know its features and limitations then you canskip this very small but highly informative section, over which I laboured long and hard for those thatdidn't know. If you are really sure, jump to theSetup Section.

    What is Perl?

    Perl is a programming language. Perl stands for Practical Report and Extraction Language. You'llnotice people refer to 'perl' and "Perl". "Perl" is the programming language as a whole whereas 'perl'is the name of the core executable. There is no language called "Perl5" -- that just means "Perlversion 5". Versions of Perl prior to 5 are very old and very unsupported.

    Some of Perl's many strengths are:

    Speed of development. You edit a text file, and just run it. You can develop programs veryquickly like this. No separate compiler needed. I find Perl runs a program quicker than Java,let alone compare the complete modify-compile-run-oh-no-forgot-that-semicolon sequence.

    Power. Perl's regular expressions are some of the best available. You can work with objects,

    sockets...everything a systems administrator could want. And that's just the standarddistribution. Add the wealth of modules available on CPAN and you have it all. Don't equatescripting languages with toy languages.

    Usuability. All that power and capability can be learnt in easy stages. If you can write abatch file you can program Perl. You don't have to learn object oriented programming, butyou can write OO programs in Perl. If autoincrementing non-existent variables scares you,make perl refuse to let you. There is always more than one way to do it in Perl. You decideyour style of programming, and Perl will accommodate you.

    Portability. On the Superhighway to the Portability Panacea, Perl's Porsche powers pastJava's jaded jalopy. Many people develop Perl scripts on NT, or Win95, then just FTP themto a Unix server where they run. No modification necessary.

    Editing tools You don't need the latest Integrated Development Environment for Perl. Youcan develop Perl scripts with any text editor. Notepad, vi, MS Word 97, or even direct off theconsole. Of course, you can make things easy and use one of the many freeware orshareware programmer's file editors.

    Price. Yes, 0 guilders, pounds, dmarks, dollars or whatever. And the peer to peer support isalso free, and often far better than you'd ever get by paying some company to answer thephone and tell you to do what you just tried several times already, then look up the samereference books you already own.

    http://www.netcat.co.uk/rob/http://www.netcat.co.uk/rob/mailto:[email protected]:[email protected]://www.sthomas.net/roberts-perl-tutorial.htm#setuphttp://www.sthomas.net/roberts-perl-tutorial.htm#setuphttp://www.sthomas.net/roberts-perl-tutorial.htm#setuphttp://www.sthomas.net/roberts-perl-tutorial.htm#setupmailto:[email protected]://www.netcat.co.uk/rob/
  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    4/118

    What is ActivePerl? Are the other Perls inactive?

    A company named ActiveState exists to provide Perl tools for the Win32 environment. ActiveStateused to be ActiveWare, and before that it was sort of a part of Hip Communications. It now appearsto be happy with its current name, having not changed it for over a year. Win32 means, at the time of

    writing, Windows 95, Windows 98 and Windows NT. It does notmean Windows 3.11, even withWin32s installed.

    Prior to Perl version 5.005, there was one version of Perl for Win32, and another for all the othersystems. The other version was known as the "native version".

    The Win32 version was developed by ActiveState, called "Perl for Win32" and typically laggedslightly behind the native version. As of the 5.005 release, Perl for Win32 and the native versionhave merged -- the native version now supports Win32 directly and doesn't need any tweaking byActiveState.

    ActiveState have dropped "Perl for Win32" and renamed their distribution, which comes with anInstallShield installer, "ActivePerl".

    Incidentally, a few months before 5.005 merge the native Perl version was changed so it would runon Win32 directly. This version was best known by the creator's name, "Gurusamy Sarathy".However, there were still quite a few differences between it and Perl for Win32, so many people ranboth. The merge brought the best of both worlds together.

    Can I run Perl on my computer?

    Probably. Perl runs on everything from Amigas to Macintoshes to Unix boxen. Perl also runs on

    Microsoft operating systems, namely Windows 95, Windows 98 and Windows NT 3.51 and later.There are versions of Perl that run on earlier versions of these operating systems but they are nolonger developed or supported. Seehttp://www.perl.com/for full details.

    What can I do with Perl ?

    Just two popular examples :

    The Internet

    Go surf. Notice how many websites have dynamic pages with .pl or similar as the filenameextension? That's Perl. It is the most popular language for CGI programming for many reasons, mostof which are mentioned above. In fact, there are a great many more dynamic pages written with perlthat may not have a .pl extension. If you code in Active Server Pages, then you should try usingActiveState's PerlScript. Quite frankly, coding in PerlScript rather than VBScript or JScript is likedriving a car as opposed to riding a bicycle. Perl powers a good deal of the Internet.

    http://www.perl.com/http://www.perl.com/http://www.perl.com/http://www.perl.com/
  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    5/118

    Systems Administration

    If you are a Unix sysadmin you'll know about sed, awk and shell scripts. Perl can do everything theycan do and far more besides. Furthermore, Perl does it much more efficiently and portably. Don'ttake my word for it, ask around.

    If you are an NT sysadmin, chances are you aren't used to programming. In which case, theadvantages of Perl may not be clear. Do you need it? Is it worth it?

    After you read this tutorial you will know more than enough to start using Perl productively. Youreally need very little knowledge to save time. Imagine driving a car for years, then realising it hasfive gears, not four. That's the sort of improvement learning Perl means to your daily sysadminery.When you are proficient, you find the difference like realising the same car has a reverse gear andyou don't have to push it backwards. Perl means you can be lazier. Lazy sysadmins are goodsysadmins, as I keep telling my boss.

    A few examples of how I use Perl to ease NT sysadmin life:

    User account creation. If you have a text file with the user's names in it, that is all youneed. Create usernames automatically, generate a unique password for each one and createthe account, plus create and share the home directory, and set the permissions.

    Event log munging. NT has great Event Logging. Not so great Event Reading. You can usePerl to create reports on the event logs from multiple NT servers.

    Anything else that you would have used a batch file for, or wished that you could automatesomehow. Now you can.

    What can't I do with Perl ?

    The question is, "what shouldn't I do with Perl". Write office suites is one answer. Perl, like mostscripting languages, is a glue language designed for short and relatively simple tasks. Just don'tequate this philosophy with a lack of power or "serious" features.

    Support

    See the FAQs at www.perl.com. Of course there are Usenet groups, but also many mailing lists.Microsoft Windows users will be interested in those hosted byhttp://www.activestate.com/whichdiscuss all things Perl and Windows.

    Please, before you ask any question, anywhere:

    1. Make sure you read the group charter. Many people put time and effort into the creation ofthose charter in the interests of efficient discussion, so don't degrade the discussion qualityand insult us by ignoring the guidelines.

    http://www.activestate.com/http://www.activestate.com/http://www.activestate.com/http://www.activestate.com/
  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    6/118

    2. Read the FAQs at least twice. Try and find related FAQs. Try hard. You won't be popular ifyou post a question starting "I've looked at all the FAQs..." and then ask something thatactually isin the FAQs. Or the manual for that matter. Believe me, it will be patently obviousto all on the list if you haven't done your homework.

    3. Carefully phrase the questions and provide source code because if you do that, you maywell end up solving the problem yourself because you have thought it through a little more.

    Think to yourself -- honestly -- if I was a busy Perl Professional, would I want to answer myown question?

    Does it clearly state what I want an answer to? Preferably just one question at a time. Am I beingunreasonable, for example asking for someone to code it for me? Have I shown evidence that I havetried to help myself? Have I made any mistakes in grammar? Is it polite? Is there enough informationin there for the answer to be given?

    Why should you care? Well, if you ask poorly-formed questions or those already answered in theFAQ...let's just say you won't get the answers you want. If you care about your online reputation andwasting other people's time -- two more reasons.

    SetupThere are four stages:

    1. Get the software.2. Install it.3. Run a test Script.4. Celebrate or troubleshoot.

    1. Getting the Software

    An old version of Perl for Win32 is included with the Windows NT Resource Kit. It is sadly out ofdate. Follow the steps below to get a newer version. Having said that, you can complete the tutorial

    with the Resource Kit version but you should upgrade as soon as you can.

    Go tohttp://www.activestate.com/and follow the links to download ActivePerl. It will be a single file,and the name will be something like api508e.exe. The i stands for Intel. If you have an Alpha,downloadapaXXXe.exe. If you're not sure, download the Intel version.

    The 508e is the version number, so expect this to change quite rapidly. The file size will be just over5Mb, so it will take a while to download via modem. If you know how to use FTP,tryftp.activestate.com/activeperl/ .

    http://www.activestate.com/http://www.activestate.com/http://www.activestate.com/http://www.activestate.com/
  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    7/118

    When you find ActivePerl, save the file into any directory you please. I like to organise mydownloads into c:\downloads but that is just personal preference. As long as ActivePerl ends upon your hard disk somewhere it doesn't matter.

    2. Installation

    So you now have apixxxx.exe. If you forget where you saved it, don't panic, just run WindowsExplorer and search for api*e.exe

    1. Double-click the apixxxx.exe. You'll see the fantastic ActivePerl graphic and be advisedto close all open applications before proceeding. The lizard thing is a gecko, which adornsthe famous O'Reilly book "Learning Perl on Win32 Systems". This tutorial is aimed at a morebasic level than that book, in terms of the author's knowledge, intended audience and qualityof humour.

    2. Agree to the license agreement or cancel the install, stop this tutorial and deny yourselfany hope of hackership.

    3. Destination directory is whatever you want. I usually install Perl in c:\progs\perl rather

    than c:\program files\perl because many Win32 programs don't properly handle longfilenames, let alone those with spaces in. Or you could accept the default. Your choice.4. Select Components. All you'll need for this tutorial is "Perl for Win32 Core", but installing the

    "Online Help and Documentation" and "Example Files" is highly recommended. If you runInternet Information Server (IIS) 3 or later, or Personal Web Server (PWS), then install "Perlfor ISAPI" and "PerlScript" too, although don't try either of these until you are proficient withthe basics. The phrase running before walking comes to mind.

    5. Select Options.o "Associate '.pl' with Perl.exe". If you select this option then you can just type in the

    name of a script at the command line, or double-click it and the script will run. If youdon't, then in order to get a script to execute you'll need to type:perl myscript.plto execute myscript.pl. Personally, I prefer double-clicking to allow me to edit the

    file so I do not select this option. Also, perl has a plethora of command linearguments which are difficult to pass to a script if you run it by association. For thepurposes of this tutorial I'm assuming that you haven't associated .pl with perl.

    o "Add the Perl bin directory to your path". Do this, otherwise you'll have to specifythe full path to perl.exe every time you use it. Not fun.

    o "Standard I/O redirection for IIS". If you run IIS or PWS, select this. It is a GoodThing. Understand it later.

    6. IIS Options If you use IIS or PWS you'll have this screen -- just accept both options.7. Program Folder whatever your preference is. This is just a link to the documentation, to the

    perl.exe itself.8. Confirmation make sure that what is displayed is what you have selected...9. The install program will now copy files. At the end it will run a few perl scripts itself, which

    briefly appear as DOS boxes. Don't worry, it is all quite normal.10. Release notes. Well worth a read.11. Reboot! Just so the path statement takes effect. In any case, it is always good practice to

    reboot after a new install.

    3. Testing - Your First Perl Script

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    8/118

    So you know what this tutorial is designed to do. You know what Perl is designed to do, and youhave even installed it. It is now time to start the tutorial proper, and actually hack some code.

    The Tutorial: The Journey Begins

    Your First Time

    Assuming all has gone to plan, you can now create your first Perl script. Follow these instructions,but before you start read them through once, then begin. That's a good idea with any form ofcomputer-related procedure. So, to begin:

    1. Create a new directory for your perl scripts, separate to your data files and the perlinstallation. For example, c:\scripts\, which is what I'll assume you are using in thistutorial.

    2. Start up whatever text editor you're going to hack Perl with. Notepad.Exe is just fine. If youcan't find Notepad on your Start menu, press the Start button, then select Run, type in'notepad' and click OK.

    3. Type the following in Notepad

    print "My first Perl script\n";

    4. Save the to c:\scripts\myfirst.pl. Be careful! Notepad will may save files with

    a .txt extension, so you will end up with myfirst.txt.pl by default. Perl won't mind, it'llstill execute the file. If your version of Notepad does this, select "All files" before saving orrename the file then load it again. Better yet, use a decent text editor!

    5. You don't need to exit Notepad -- keep it open, as we'll be making changes very soon.6. Switch to your command prompt. If you don't know how to start a command prompt, click

    'Start' and then 'Run'. If using Windows 9x, type in 'command' and press enter. If using NT,type in 'cmd' and press Enter.

    7. Change to your perl scripts directory, for example cd \scripts .8. Hold your breath, and execute the script: perl myfirst.pl

    and you'll see the output. Welcome to the world of Perl ! See what I mean about it being easy to start? However, it is difficult to finish with Perl once you begin :-)

    What if it doesn't...?

    So you typed in perl myfirst.pl and you didn't see My first Perl script on the screen. Ifyou saw "bad command or filename" then either you haven't installed Perl or perl.exe is not in yourpath. Probably the latter. Reboot, then try again.

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    9/118

    If you saw Can't open perl script "xxxx.pl": No such file or directory then perl isdefintely installed, but you have either got the name of the script wrong or the script is not in thesame directory as where you are trying to run it from. For example, maybe you saved in scriptin c:\windows and you are in c:\scripts so of course Perl complains it can't find the script.Could you? Well, don't expect Perl to then. You don't have to run the script from the directory inwhich it resides, but it is easier.

    Assuming it's now all right...

    W need to analyse what's going on here a little. First note that the line ends with a semicolon ; .Almost all lines of code in Perl have to end with semicolons, and those that don't have to will acceptsemicolons anyway. The moral is -- use semicolons. Sorry; the moral is; use semicolons.

    Oh, one more thing -- if you haven't already done so, continue breathing.

    Also note the \n . This is the code to tell Perl to output a newline. What's a newline? Deletethe \n from the program and run it again:

    print "My first Perl script";

    and all should become clear. You have now written your first Perl script.

    Shebang

    Almost every Perl book is written for UN*X, which is a problem for Win32. This leads to scripts like:

    #!c:/perl/perl.exe

    print "I'm a cool Perl hacker\n";

    The function of the 'shebang' line is to tell the shell how to execute the file. Under UNIX, this makessense. Under Win32, the system must already know how to execute the file before it is loaded so theline is not needed.

    However, the line is not completely ignored, as it is searched for any switches you may have givenPerl (for example -w to turn on warnings).

    You may also choose to add the line so your scripts run directly on UNIX without modification, asUNIX boxes probably doneed it. Win32 systems do not. We shall continue with the lesson.

    Variables

    Scalars

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    10/118

    So Perl is working, and you are working with Perl. Now for something more interesting than simpleprinting. Variables. Let's take simple scalar variables first. A scalar variable is a single value.Like$var=10 which sets the variables $var to the value of 10. Later, we'll look at lists like arraysand hashes, where @var refers to more than one value. For the moment, remember that Scalar isSingular. If weird metaphors help, think of lots of scaly snakes at a singles bar. If that didn't help, Iapologise for putting the thought into your mind.

    $ % @ are Good Things

    If you have any experience with other programming languages you might be surprised by thecode $var=10. With most languages, if you want to assign the value 10 to a variablecalled var you'd writevar=10.

    Not so in Perl. This is a Feature. All variables are prefixed with a symbol such as $ @ % . This hascertain advantages, like making programs easier to read. Honestly, I'm serious! It just takes somegetting used to. The prefixes mean that you can see where the variables are quite easily. And notonly that, what sort of variable it is. The human language German has a similar principle (exceptnouns are capitalised, not prefixed with $ and Perl is easier to pronounce). You'll agree later, I think.

    So, ever onwards. Time to try some more variables:

    $string="perl";$num1=20;$num2=10.75;print "The string is $string, number 1 is $num1 and number 2 is $num2\n";

    Typing

    A closer look...notice you don't have to say what type of variable you are declaring. In otherlanguages you need to say if the variable is a string, array, what sort of number it is and so on. Youmight even have to declare what type of number it is. As an example, in Java you'd been sayingthings like int var=10 which defines the variable var as an integer, with the value 10.

    So, why do these other programming languages force you to declare exactly what your variablesare? Wouldn't it be easier if we could just not bother?

    For short programs, yes. For really big projects with many programmers working on the sameapplication, no. That's because forcing variable type declaration also forces a certain discipline andrigour which is what you need on big projects.

    As you know, Perl is not designed for gigantic software engineering efforts. It is all about small, quickprograms. For these purposes you don't need the rigour of variable controls as much, so Perldoesn't bother.

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    11/118

    This idea of forcing a programmer to declare what sort of variable is being created is called typing.As Perl doesn't by default enforce any rules on typing, it is said to be a loosely typed language, asopposed to something like C++ which is strongly typed.

    Variable Interpolation

    We still haven't finished learning from that humble bit of code. To refresh your memory, here it isagain:

    $string="perl";$num1=20;$num2=10.75;print "The string is $string, number 1 is $num1 and number 2 is $num2\n";

    Notice the way the variables are used in the string. Sticking variables inside of strings has atechnical term - "variable interpolation". Now, if we didn't have the handy $ prefix for we'd have

    to do something like the example below, which is pseudocode. Pseudocode is code todemonstrate a concept, not designed to be run. Like certain Microsoft software.

    print "The string is ".string." and the number is ".num."\n";

    which is much more work. Convinced about those prefixes yet ?

    Try running the following code:

    $string="perl";$num=20;print "Doubles: The string is $string and the number is $num\n";

    print 'Singles: The string is $string and the number is $num\n';

    Double quotes allow the aforementioned variable interpolation. Single quotes do not. Both have theiruses as you will see later, depending on whether you wish to interpolate anything.

    Changing Variables

    Auto(de|in)crements

    If you want to add 1 to a variable you can, logically, do this; $num=$num+1 . There is a shorter wayto do this, which is $num++. This is an autoincrement. Guess what this is; $num-- . Yes, anautodecrement.

    This example illustrates the above:

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    12/118

    $num=10;print "\$num is $num\n";

    $num++;print "\$num is $num\n";

    $num--;print "\$num is $num\n";

    $num+=3;print "\$num is $num\n";

    The last example demonstrates that it doesn't have to be just 1 you can add or decrease by.

    Escaping

    There's something else new in the code above. The \ . You can see what this does --it 'escapes' the special meaning of $ .

    Escaping means that just the $ symbol is printed instead of it referring to a variable.

    Actually \ has a deeper meaning -- it escapes all of Perl's special characters, not just $ . Also, itturns some non-special characters into something special. Like what ? Like n . Add themagic \ and the humble 'n' becomes the mighty NewLine ! The \ character can also escape itself.So if you want to print a single \ try:

    print "the MS-DOS path is c:\\scripts\\";

    Oh, '\' is also used for other things like references. But that's not even covered here.

    There is a technical term for these 'special characters' such as @ $ %. They arecalled metacharacters. Perl uses plenty of metacharacters. In fact, you'll wear your keyboard prettyevenly during a night's perl hacking. I think it is safe to say that Perl uses every possible keystrokeand shifted keystroke on a standard US PC keyboard.

    You'll be working with all sorts of obscure characters in your Perl hacking career, and I also meanthose on your keyboard. This has earned perl a reputation for being difficult to understand. That'sentirely true. Perl doeshave such a reputation, no doubt about it.

    Is the reputation justified? In my opinion, Perl does have a short but steep learning curve to beginwith simply because it is so different. However, once you learn the character meanings reading perlcode becomes much easier precisely because of all these strange characters.

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    13/118

    Context: About Perl and @^$%&~`/?

    Perl uses so many weird characters that there aren't enough to go round. So sometimes the samecharacter has two or more meanings, depending on its context. As an example, the humbledot .can join two variables together, act as a wildcard or become a range operator if there are two of

    them together. The caret ^ has different effects in [^abc] as opposed to [a^bc] .

    If this sounds crazy, think about the English language. What do the following mean to you ?

    MEAN POLISH LIKE

    Mean is, in one context, is a word to used describe the purpose of something. It is also another wordfor average. Furthermore, it describes a nasty person, or a person who doesn't like spending money,and is used in slang to refer to something impressive and good.

    That's five different uses for 'mean', and you don't have any trouble understanding which oneI mean due to context.

    Polish, when capitalised, can either mean pertaining to the country Poland, or the act of makingsomething shiny. And 'like' can mean similar to, or affection for.

    So, when you speak or write English (think of two, to and too) you know what these words mean bytheir context. It is exactly the same way with Perl. Just don't assume a given metacharacter alwaysmeans what you first thought it did.

    To finish off this section, try the following:

    Strings and Increments$string="perl";$num=20;$mx=3;

    print "The string is $string and the number is $num\n";

    $num*=$mx;$string++;print "The string is $string and the number is $num\n";Note the easy shortcut *= meaning 'multiply $num by $mx' or, $num=$num*$mx

    .Of course Perl supports the usual + - * / ** % operators. The last two areexponentiation (to the power of) and modulus (remainder of x divided byy).Also note the way you can increment a string ! Is this language flexibleor what ?

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    14/118

    Print: A List Operator

    The print function is a list operator. That means it accepts a list of things to print, separated bycommas. As an example:

    print "a doublequoted string ", $var, 'that was a variable called var',$num," and a newline \n";Of course, you just put all the above inside a singledoublequoted string:print "a doublequoted string $var that was a variable called var $num anda newline \n";to achieve the same effect. The advantage of using the print function inlist contextis that expressions are evaluated before being printed. For example, trythis:$var="Perl";$num=10;print "Two \$nums are $num * 2 and adding one to \$var makes $var++\n";

    print "Two \$nums are ", $num * 2," and adding one to \$var makes ",$var++,"\n";

    You might have been slightly surprised by the result of that last experiment. In particular, whathappened to our variable $var ? It should have been incremented by one, resulting in Perm. Thereason being that 'm' is the next letter after 'l' :-)

    Actually, it wasincremented by 1. We are postincrementing$var++ the variable, ratherthan preincrementing it.

    The difference is that with postincrements, the value of the variable is returned, then the operation is

    performed on it. So in the example above, the current value of $var was returned tothe printfunction, then 1 was added. You can prove this to yourself by adding the line print"\$var is now $var\n"; to the end of the example above.

    If we want the operation to be performed on $var before the value is returned to the print function,then preincrement is the way to go. ++$var will do the trick.

    Subroutines -- A First Look

    Let's take a another look at the example we used to show how the autoincrement system works.Messy, isn't it ? This is Batch File Writing Mentality. Notice how we use exactly the same code fourtimes. Why not just put it in a subroutine?

    $num=10; # sets $num to 10&print_results; # prints variable $num

    $num++;&print_results;

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    15/118

    $num*=3;&print_results;

    $num/=3;&print_results;

    sub print_results {print "\$num is $num\n";

    }

    Easier and neater. The subroutine can go anywhere in your script, at the beginning, end,middle...makes no difference. Personally I put all mine at the bottom and reserve the top part forsetting variables and main program flow.

    A subroutine is just some code you want to use more than once in the same script. In Perl, asubroutine is a user-defined function. There is no difference. For the purposes of clarity I'll refer tothem as subroutines.

    A subroutine is defined by starting with sub then the name. After that you need a curly leftbracket { , then all the code for your subroutine. Finish it off with a closing brace } . The areabetween the two braces is called a block. Remember this. There are such things as anonymoussubroutines but not here. Everything here has a name.

    Subroutines are usually called by prefixing their name with an ampersand, that is one of these -- & ,like so &print_results; . It used to be cool to omit the & prefix but all perl hackers are nowencouraged to use it to avoid ambiguity. Ambiguity can hurt you if you don't avoid it.

    If you are worrying about variable visibility, don't. All the variables we are using so far are visibleeverywhere. You can restrict visibility quite easily, but that's not important right now. If you weren'tworrying about variable visibility, please don't start. I'd tell you it's not important but that'll only makeyou worried. (paranoid ?) We'll cover it later.

    Comments

    Did you see a # crept in there. That's a comment. Everything after a # is ignored. You can'tcontinue it onto a newline however, so if your comment won't fit on one line start a new one with # .There are ways to create Plain Old Documentation (POD) and more ways to comment but they arenot detailed here.

    Comparisons

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    16/118

    An iffy start

    An if statement is simple. if the day is Sunday, then lie in bed. A simple test, with twooutcomes. Perl conversion (don't run this):

    if ($day eq "sunday") {&lie_in_bed;

    }

    You already know that &lie_in_bed is a call to a subroutine. We assume $day is set earlier in theprogram. If $day is not equal to 'Sunday' &lie_in_bed is not executed (pity). You don't need tosay anything else. Try this:

    $day="sunday";

    if ($day eq "sunday") {print "Zzzzz....\n";

    }Note the syntax. The if statement requires something to test for Truth.This expression mustbe in (parens), then you have the braces to form a block.

    The Truth According to Perl

    There are many Perl functions which test for Truth. Some are if, while, unless . So it isimportant you know what truth is, as defined by Perl, not your tax forms. There are three main rules:

    1. Any string is true except for "" and "0".

    2. Any number is true except for 0. This includes negative numbers.3. Any undefined variable is false. A undefined variable is one which doesn't have a value, ie

    has not been assigned to.

    Some example code to illustrate the point:

    &isit; # $test1 is at this moment undefined

    $test1="hello"; # a string, not equal to "" or "0"&isit;

    $test1=0.0; # $test1 is now a number, effectively 0

    &isit;

    $test1="0.0"; # $test1 is a string, but NOT effectively 0 !&isit;

    sub isit {if ($test1) { # tests $test1 for truth

    or notprint "$test1 is true\n";

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    17/118

    } else { # else statement if it isnot true

    print "$test1 is false\n";}

    }

    The first test fails because $test1 is undefined. This means it has notbeen created byassigning a value to it. So according to Rule 3 it is false. The last twotests areinteresting. Of course, 0.0 is the same as 0 in a numeric context. But itis not thesame as 0 in a string context, so in that case it is true.

    So here we are testing single variables. What's more useful is testing the result of an expression. Forexample, this is an expression; $x * 2 and so is this; $var1 + $var2 . It is the end result ofthese expressions that is evaluated for truth.

    An example demonstrates the point:

    $x=5;$y=5;

    if ($x - $y) {print '$x - $y is ',$x-$y," which is true\n";

    } else {print '$x - $y is ',$x-$y," which is false\n";

    }

    The test fails because 5-5 of course is 0, which is false. The print statement might look a little

    strange. Remember that print is a list operator? So we hand it a list. First item, a single-quotedstring. It is single quoted because it we do not want to perform variable interpolation on it. Next itemis an expression which is evaluated, and the result printed. Finally, a double-quoted string is usedbecause we want to print a newline, and without the doublequotes the \n won't be interpolated.

    What is probably more useful than testing a specific variable for truth is equality testing. Forexample, has your lucky number been drawn?

    $lucky=15;$drawnum=15;

    if ($lucky == $drawnum) {

    print "Congratulations!\n";} else {print "Guess who hasn't won!\n";

    }

    The important point about the above code is the equality operator, == .

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    18/118

    Equality and Perl

    Now pay close attention, otherwise you'll end up posting an annoying question somewhere. This is aFAQ, as in a Frequently Asked Question.

    The symbol = is an assignment operator, nota comparison operator. Therefore:

    if ($x = 10) is always true, because $x has been assignedthe value 10 successfully.

    if ($x == 10) comparesthe two values, which might not be equal.

    So far we have been testing numbers, but there is more to life than numbers. There are strings too,and these need testing too.

    $name = 'Mark';

    $goodguy = 'Tony';

    if ($name == $goodguy) {print "Hello, Sir.\n";

    } else {print "Begone, evil peon!\n";

    }

    Something seems to have gone wrong here. Obviously Mark is different to Tony, so why does perlconsider them equal?

    Mark and Tony areequal -- numerically. We should be testing them as strings, not as numbers. Todo this, simply substitute == for eq and everything will work as expected.

    All Equality is Not Equal: Numeric versus String

    There are two types of comparison operator; numeric and string. You've already seentwo, == and eq. Run this:

    $foo=291;$bar=30;

    if ($foo < $bar) {

    print "$foo is less than $bar (numeric)\n";}

    if ($foo lt $bar) {print "$foo is less than $bar (string)\n";

    }

    The lt operator compares in a string context, and of course < compares in a numeric context.

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    19/118

    Alphabetically, that is in a string context, 291 comes before 30. It is actually decided by the ASCIIvalue, but alphabetically is close enough. Change the numbers around a little. Notice how Perldoesn't care whether it uses a string comparison operator on a numeric value, or vice versa. This istypical of Perl's flexibility.

    Bondage and discipline are pretty much alien concepts to Perl (and the author). This flexibility does

    have a drawback. If you're on a programming precipice, threatening suicide by jumping off, Perlwon't talk you out of your decision but will provide several ways of jumping, stepping or falling to yourdoom while silently watching your early conclusion. So be careful.

    An interlude -- The Perl Motto

    The Perl Motto is; "There is More Than One Way to Do It" or TIMTOWTDI. Pronounced 'Tim-Toady'. This tutorial doesn't try and mention all possible ways of doing everything, mainly becausethe author is far too lazy. Write your Perl programs the way you want to.

    The Comparison Operators Listed

    The rest of the operators are:

    Comparison Numeric String

    Equal == eq

    Not equal != neGreater than > gt

    Less than < lt

    Greater than or equal to >= ge

    Less than or equal to

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    20/118

    More About If: Multiples

    More about if statements. Run this:

    $age=25;$max=30;

    if ($age > $max) {print "Too old !\n";

    } else {print "Young person !\n";

    }It is easy to see what else does. If the expression is false then whateveris inthe else block is evaluated (or carried out, executed, whatever term youchoose to use).

    Simple. But what if you want another test ? Perl can do that too.

    elsif

    $age=25;$max=30;$min=18;

    if ($age > $max) {print "Too old !\n";

    } elsif ($age < $min) {

    print "Too young !\n";} else {

    print "Just right !\n";}If the first test fails, the second is evaluated. This carries on untilthere are nomore elsif statements, or an else statement is reached. An else statementis optional,and no elsif statements should come after it. Logical, really.

    There is a big difference between the above example the one below:

    if ($age > $max) {print "Too old !\n";}

    if ($age < $min) {print "Too young !\n";

    }

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    21/118

    If you run it, it will return the same result - in this case. However, it is Bad Programming Practice. Inthis case we are testing a number, but suppose we were testing a string to see if it contained R or S.It is possible that a string could contain bothR and S. So it would pass both 'if' tests. Usingan elsif avoids this. As soon as the first statement is true, no more elsif statements (andno else statement) are executed.

    You don't need to take up a whole three lines:

    print "Too old\n" if $age > $max;print "Too old\n" unless $age < $max;

    I added some whitespace there for aesthetic beauty. There are other operators that you can useinstead of if and unless , but that's for later on.

    Incidentally, the two lines of code above do not do exactly the same thing. Consider a maximum ageof 50 and input age of 50. Therefore, you should be very careful about your logic when writing code(nice obvious statement there).

    For those that were wondering, Perl has no case statement. This is all explained in the FAQ, whichis located at http://www.perl.com/.

    User Input

    STDIN and other filehandlesSometimes you have to interact with the user. It is a pain, but sometimes necessary, especially forthe live ones. To ask for input and do something with it try this:

    print "Please tell me your name: ";$name=;print "Thanks for making me happy, $name !\n";

    New things to learn here. Firstly, . STDIN is a filehandle.Filehandles are whatyou use to interact with things such as files, console input, socket

    connections and more.

    You could say STDIN is the standard source for input. Guess what STDIN stands for. In this casethe STDIN filehandle is reading from the console.

    The angle brackets read data from a filehandle. Exactly how much is dependent on what you do,but in this case it is whatever was input at the prompt.

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    22/118

    So we are reading from the STDIN filehandle. The value is assigned to $name and printed. Any ideawhy the ! ends up on a new line ? on a new lineon a newline ????

    As you pressed Enter, you of course included a newline with your name. The easy way to get rid of itis to chop it off:

    Chop

    print "Please tell me your name: ";$name=;chop $nameprint "Thanks for making me happy, $name !\n"

    and that fails with a syntax error. Can you spot why? Look at the errorcode, look at theline number and see where the syntax is wrong. The answer is a missingsemicolon( ; ) on the end of the last two lines.

    If you add a ; to the end of line 3, but not to the last line, then the program works as it should. Thisis because Perl doesn't need a semicolon to end the last statement of a block. However, I'd adviseending all your statements with semicolons because you may well be adding more code to them andit is only one little keystroke.

    When you add the semicolon(s), the program runs correctly. The chop function removes the lastcharacter of whatever it is given to chop, in this case removing the newline for us. In fact, that can beshortened:

    print "Please tell me your name: ";chop ($name=);

    print "Thanks for making me happy, $name !";

    The parentheses ( ) force chop to act on the result of what is inside them. So $name= isevaluated first, then the result from that, which is $name , is chopped. Try it without.

    You can read from STDIN as much as you like. For your entertainment I have created asophisticated multinational greeting machine:

    print "Please tell me your name: ";chop ($name=);

    print "Please tell me your nationality: ";chop ($nation=);

    if ($nation eq "British" or $nation eq "New Zealand") {print "Hallo $name, pleased to meet you!\n";

    } elsif ($nation eq "Dutch" or $nation eq "Flemish") {print "Hoi $name, hoe gaat het met u vandaag?!\n";

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    23/118

    } else {print "HELLO!!! SPEAKEEE ENGLIEESH???\n";

    }

    Aside from demonstrating the native English speaker's linguistic talents, this script also introduces

    the or logical operator. We'll cover or and its associates in more detail later on. First, a word ofwarning.

    Chopping is dangerous, as my friend One Hand Harold will tell you. Everyone is concerned aboutvarious forms of safety these days, and your perl code should be no exception.

    Safe Chopping with Chomp

    Rather than just wantonly remove the last character regardless of whatever it is, without a care in theworld, just simply consigning the poor little thing to the Great Bit Bucket in the Sky, you can remove

    the last character only if it is a newline with chomp :

    chomp ($name=);

    At this point the perl gurus are screaming "I found an error !". Well, chomp doesn't always removethe last character if it is a newline but if it doesn't, you have set a special variable, namely $/ , tosomething different. I presume that if you do set $/ you know what it does. It is explained later inthis very document. Of course, being a good pupil, you wouldn't experiment with the unknown,blindly changing things just for the hell of it to see what happens.

    If you don't, you'll never learn anything useful.

    Arrays

    Lists, herds -- what are arrays?

    Perl has two types of array, associative arrays (hashes) and arrays. Both types are lists. A list is justa collection of variables referred to as the collection, not as individual elements.

    You can think of Perl's lists as a herd of animals. List context refers to the entire herd, scalar contextrefers to a single element. A list is a herd of variables. The variables don't have to be all of the sametype -- you might have a herd of ten sheep, three lions and two wolves. It would probably be justthree lions and one wolf before long, but bear with me. In the same way, you might have a Perl list ofthree scalar variables, two array elements and ten hash elements.

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    24/118

    Certain types of lists are known by certain names. Just as a herd of sheep is called a flock, a herd oflions is called a pride, a herd of wolves is called a pack and a herd of managers a confusion, sometypes of Perl list have a special names.

    Basic Array Work

    For example, an array is an ordered list of scalar variables. This list can be referred to as awhole, or you can refer to individual elements in the list. The program below defines a an array,called@names . It puts five values into the array.

    @names=("Muriel","Gavin","Susanne","Sarah","Anna");

    print "The elements of \@names are @names\n";print "The first element is $names[0] \n";print "The third element is $names[2] \n";

    print 'There are ',scalar(@names)," elements in the array\n";

    Firstly, notice how we define @names . As it is in a list context, we are using parens. Each valueis comma separated, which is Perl's default list delimiter. The double quotes are not necessary,but as these are string values it makes it easier to read and change later on.

    Next, notice how we print it. Simply refer to it as a whole, that is in list context.. List context meansreferring to more than one element of a list at a time. The code print @names; will work perfectlywell too. But....

    I usually learn something about Perl every time I work with it. When running a course, a student

    taught me this trick which he had discovered:

    @names=("Muriel","Gavin","Susanne","Sarah","Anna","Paul","Trish","Simon");

    print @names;print "\n";print "@names";When a list is placed inside doublequotes, it is space delimited wheninterpolated. Useful.

    If we want to do anything with the array as a list, that is doing something with more than one value,

    then refer to the array as @array . That's important. The @ prefix is used when you want to refer tomore than one element of a list.

    When you refer to more than one, but not all elements of an array that is known as a slice . Cakeanalogies are appropriate. Pie analogies are probably healthier but equally accurate.

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    25/118

    Elements of Arrays

    Arrays are not much use unless we can get to individual elements. Firstly, we are dealing with asingle element of the list, so we cannot use @ which refers to multiple elements of the array. It is asingle, scalar variable, so $ is used. Secondly, we must specify which element we want. That's

    easy - $array[0] for the first, $array[1] for the second and so forth. Array indexes start at 0,unless you do something which is so highly deprecated ('deprecated' means allowed, usually forbackwards compatibility, but disapproved of because there are better ways) I'm not even going tomention it.

    Finally, we force what is normally list context (more than one element) into scalar context (singleelement) to give us the amount of elements in the array. Without the scalar , it would be the sameas the second line of the program.

    How to refer to elements of an array

    Please understand this:

    $myvar="scalar variable";@myvar=("one","element","of","an","array","called","myvar");

    print $myvar; # refers to the contents of a scalar variable calledmyvarprint $myvar[1]; # refers to the second element of the array myvarprint @myvar; # refers to all the elements of array myvar

    The two variables $myvar and @myvar are not, in any way, related. Not even distantly. Technically,

    they are in different namespaces.

    Going back to the animal analogy, it is like having a dog named 'Myvar' and a goldfish called 'Myvar'.You'll never get the two mixed up because when you call 'Myvar !!!!' or open a can of dog food the'Myvar' dog will come running and goldfish won't. Now, you couldn't have two dogs called 'Myvar'and in the same way you can't have two Perl variables in the same namespace called 'Myvar'.

    More ways to access arrays

    The element number can be a variable.

    print "Enter a number :";chomp ($x=);

    @names=("Muriel","Gavin","Susanne","Sarah","Anna");

    print "You requested element $x who is $names[$x]\n";

    print "The index number of the last element is $#names \n";

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    26/118

    This is useful. Notice the last line of the example. It returns the indexnumber ofthe last element. Of course you could always just do this$last=scalar(@names)-1; butthis is more efficient. It is an easy way to get the last element, asfollows:

    print "Enter the number of the element you wish to view :";chomp ($x=);

    @names=("Muriel","Gavin","Susanne","Sarah","Anna","Paul","Trish","Simon");

    print "The first two elements are @names[0,1]\n";print "The first three elements are @names[0..2]\n";print "You requested element $x who is $names[$x-1]\n"; # startsat 0print "The elements before and after are : @names[$x-2,$x]\n";print "The first, second, third and fifth elements are @names[0..2,4]\n";

    print "a) The last element is $names[$#names]\n"; # one way

    print "b) The last element is @names[-1]\n"; # different way

    It looks complex, but it is not. Really. Notice you can have multiplevalues separatedby a comma. As many as you like, in whatever order. The range operator ..gives youeverything between and including the values. And finally look at how weprint the lastelement - remember $#names gives us a number ? Simply enclose it insidesquare bracketsand you have the last element.

    Do also note that because element accesses such as [0,1] are more than one variable, we cannot

    use the scalar prefix, namely the $ symbol. We are accessing the array in list context, so we usethe @ symbol. Doesn't matter that it is not the entire array. Remember, accessing more than oneelement of an array but not the entire array is called a slice. I won't go over the food analogies again.

    For Loops

    A for Loop demonstrated

    All well and good, but what if we want to load each element of the array in turn ? Well, we could builda for loop like this:

    @names=("Muriel","Gavin","Susanne","Sarah","Anna","Paul","Trish","Simon");

    for ($x=0; $x

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    27/118

    }

    which sets $x to 0, runs the loop once, then adds one to $x , checks it isless than$#names , if so carries on. By the way, that was your introduction to forloops. Just

    to go into a little detail there, the for loop has three parts to it:

    Initialisation Test Condition Modification

    In this case, the variable $x is initialised to 0. It is immediately tested to see if it is smaller than, orequal to $#names . If that is true, then the block is executed once. Critically, if it is nottrue the blockis notexecuted at all.

    Once the block has been executed, the modification expression is evaluated. That's $x++ . Then,the test condition is checked to see if the block should be executed or not.

    For loops with .. , the range operator

    There is a another version:

    for $x (0 .. $#names) {print "$names[$x]\n";

    }

    which takes advantage of the range operator .. (two dots together). Thissimply gives $x thevalue of 0, then increments $x by 1 until it is equal to $#names .

    foreach

    For true beauty we must use foreach .

    foreach $person (@names) {print "$person";

    }

    This goes through each element ('iterates', another good technical wordto use)

    of @names , and assigns each element in turn to the variable $person .Then you can dowhat you like with the variable. Much easier. You can usefor $person (@names) {

    print "$person";}

    if you want. Makes no difference at all, aside from a little clarity.

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    28/118

    The infamous $_

    In fact, that gets shorter. And now I need to introduce you to $_ , which is the Default Input andPattern Searching Variable.

    foreach (@names) {print "$_";

    }

    If you don't specify a variable to put each element into, $_ is usedinstead as it isthe default for this operation, and many, many others in Perl. Includingthe print function :foreach (@names) {

    print ;}

    As we haven't supplied any arguments to print , $_ is printed as default.

    You'll be seeinga lot of $_ in Perl. Actually, that statement is not exactly true. Youwill be seeing lotof places where $_ is used, but quite often when it is used, it is notactually written.In the above example, you don't actually see $_ but you know it is there.

    A Premature End to your loop

    A loop, by its nature, continues. If that didn't make sense, start reading this sentence again.

    The old jokes are the best, aren't they?

    The joke above is a loop. You continue re-reading the sentence until you realise I'm trying to befunny. Then you exit the loop. Or maybe somebody doesn't exit it. Whatever, loops always run untilthe expression they are testing returns false. In the case of the examples above, a false value isreturned when all the elements of the array have been cycled through, and the loop ends.

    If you want an everlasting loop, just test an condition you know will always be true:

    while (1) {$x++;print "$x: Did you know you can press CTRL-C to interrupt a perl

    program?\n";}

    Another way to exit a loop is a simple foreach over the elements, as wehave seen. But if wedon't know when we want to exit a loop? For example, suppose we want toprint out a list ofnames but stop when we find one with a particular title? You are throwinga huge party,

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    29/118

    someone is allergic to vodka, and this person has drunk from the punchbowl despite beingassured by someone holding two empty bottles of Absolut that he was justusing the bottlesto convey yet more orange juice into said punch bowl. So you need adoctor, and so you write

    a Perl script to find one from the list of attendees, wanting the doctor'sname to be the lastitem printed:@names=('Mrs Smith','Mr Jones','Ms Samuel','Dr Jansen','Sir Philip');

    foreach $person (@names) {print "$person\n";last if $person=~/Dr /;

    }

    The last operator is our friend. Don't worry about the /Dr / business --that is a regularexpression which we cover next. All you need to know is that it returns

    true if the name beginswith 'Dr '. When it does return true, last is operated and the loop endsearly.

    A little more control over the premature ending: Labels

    So that's easy enough. But wait! We need a medical, human-fixer type doctor, not just anyone with aPhD. So, the same principle applies in this example here:

    @names =('Mrs Smith','Mr Jones','Ms Samuel','Dr Jansen','Sir Philip');

    @medics =('Dr Black','Dr Waymour','Dr Jansen','Dr Pettle');

    foreach $person (@names) {print "$person\n";if ($person=~/Dr /) {

    foreach $doc (@medics) {print "\t$doc\n";last if $doc eq $person;

    }}

    }

    Aside from showing one way to indent your code, this also demonstrates a

    nested loop. A nestedloop is a loop within a loop. What happens is that the @names array issearched for a 'Dr ',and if it is found then the @medics array is searched to make sure thedoctor is a human-fixingdoctor not a professor of physics or something. The regular expression hasbeen shifted intoan if statement, where it works nicely as it only returns true or false.

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    30/118

    The problem with the code is that after we find our medical doctor we want it to stop. But it doesn't. Itonly stops the loop it is in, so Dr Pettle never gets printed. However, the code just carries on with SirPhilip who is terribly sorry old chap, but can't be of any bally use at all, what ho! What we need is away to break out of the entire loop from within a nest. Like so:

    @names =('Mrs Smith','Mr Jones','Ms Samuel','Dr Jansen','Sir Philip');

    @medics =('Dr Black','Dr Waymour','Dr Jansen','Dr Pettle');

    LBL: foreach $person (@names) {print "$person\n";if ($person=~/Dr /) {

    foreach $doc (@medics) {print "\t$doc\n";last LBL if $doc eq $person;

    }}

    }

    Only two changes here. We have defined a label, namely LBL. Instead of

    breaking out fromthe current loop, which is the default, we specify a label to break outto, which is inthe outer loop. This works with as many nested loops as your brain canhandle. You don't haveto use uppercase names but for namespace reasons it is recommended, andyou can call yourlabels whatever you please. I was just being unimaginative with the nameof LBL, feel freeto invent labels called DORIS or MATILDA if that's what floats yourpersonal boat.

    Changing the Elements of an Array

    So we have @names . We want to change it. Run this:

    print "Enter a name :";chomp ($x=);

    @names=("Muriel","Gavin","Susanne","Sarah");

    print "@names\n";

    push (@names, $x);

    print "@names\n";

    Fairly self explanatory. The push function just adds a value on to the endof the array.Of course, Perl being Perl, it doesn't have to be just the one value:print "Enter a name :";

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    31/118

    chop ($x=);

    @names=("Muriel","Gavin","Susanne","Sarah");@cities=("Brussels","Hamburg","London","Breda");

    print "@names\n";

    push (@names, $x, 10, @cities[2..4]);

    print "@names\n";

    This is worth looking at in more detail. It appears there is no fifthelement of@cities , as referred to by @cities[2..4] .

    Actually, there is a fifth element. Add this to the end of the example :

    print "There are ",scalar(@names)," elements in \@names\n";

    There appear to be 8 elements in @names . However, we have just provedthere are in fact 9.The reason there are 9 is that we referred to non-existent elements of@cities , and Perlhas quite happily extended @names to suit. The array @cities remainsunchanged. Try popingthe array if you don't believe me.

    So that's push . Now for some...

    Jiggerypokery with Arrays

    @names=("Muriel","Gavin","Susanne","Sarah");@cities=("Brussels","Hamburg","London","Breda");

    &look;

    $last=pop(@names);unshift (@cities, $last);

    &look;

    sub look {print "Names : @names\n";

    print "Cities: @cities\n";}

    Now we have two arrays. The pop function removes the last element of anarray and returns it,which means you can do something like assign the returned value to avariable.The unshift function adds a value to the beginning of the array. Hope youdidn't forget that

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    32/118

    &subroutinename calls a subroutine. Presented below are the functions youcan use to work with arrays:

    A table of array hacking functions

    push Adds value to the end of the array

    pop Removes and returns value from end of array

    shift Removes and returns value from beginning of array

    unshift Adds value to the beginning of array

    Now, accessing other elements of arrays. May I present the splice function ?

    Splice

    @names=("Muriel","Sarah","Susanne","Gavin");

    &look;

    @middle=splice (@names, 1, 2);

    &look;

    sub look {print "Names : @names\n";print "The Splice Girls are: @middle\n";

    }

    The first argument for splice is an array. Then second is the offset. Theoffset is the indexnumber of the list element to begin splicing at. In this case it is 1.Thencomes the number of elements to remove, which is sensibly 1 or more inthiscase. You can set it to 0 and perl, in true perl style, won't complain.Setting to 0 is handy because splice can add elements to the middle of anarray, and if you don'twant any deleted 0 is the number to use. Like so:@names=("Muriel","Gavin","Susanne","Sarah");@cities=("Brussels","Hamburg","London","Breda");

    &look;

    splice (@names, 1, 0, @cities[1..3]);

    &look;

    sub look {print "Names : @names\n";print "Cities: @cities\n";

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    33/118

    }

    Notice how the assignment to @middlehas gone -- it is no longer relevant.

    If you assign the result of a splice to a scalar then:

    @names=("Muriel","Sarah","Susanne","Gavin");

    &look;

    $middle=splice (@names, 1, 2);

    &look;

    sub look {print "Names : @names\n";print "The Splice Girls are: $middle\n";

    }

    then the scalar is assigned the last element removed, or undef ifit doesn't work at all.

    The splice function is also a way to delete elements from an array. In fact, a discussion of :

    Deleting Variablesis in order. Suppose we want to delete Hamburg from the following array. How do we do it ?Perhaps:

    @cities=("Brussels","Hamburg","London","Breda");

    &look;

    $cities[1]="";

    &look;

    sub look {print "Cities: ",scalar(@cities), ": @cities\n";

    }

    would be appropriate. Certainly Hamburg is removed. Shame, such a great lake. But note, the arrayelement still exists. There are still four elements in @cities. So what we need is theappropriate splicefunction, which removes the element entirely.

    splice (@cities, 1, 1);

    Now that's all well and good for arrays. What about ordinary variables, such as these:

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    34/118

    $car ="Porsche 911";$aircraft="G-BBNX";

    &look;

    $car="";

    &look;

    sub look {print "Car :$car: Aircraft:$aircraft:\n";print "Aircraft exists !\n" if $aircraft;print "Car exists !\n" if $car;

    }

    It looks like we have deleted the $car variable. Pity. But think about it. It is not deleted, it is just setto the null string "". As you recall (hopefully) from previous ramblings, the null string evaluates tofalse so the if test fails.

    False values versus Existence: It is, therefore...

    Just because something is false doesn't mean to say it doesn't exist. A wig is false hair, but a wigexists. Your variable is still there. Perl does have a function to test if something exists. Existence, inPerl terms, means defined. So:

    print "Car is defined !\n" if defined $car;

    will evaluate to true, as the $car variable does in fact exist.

    This begs the question of how to really wipe variables from the face of the earth, or at least your Perlscript. Simple.

    $car ="Porsche 911";$aircraft="G-BBNX";

    &look;

    undef $car; # this undefines $car

    &look;

    sub look {print "Car :$car: Aircraft:$aircraft:\n";print "Aircraft exists !\n" if $aircraft;print "Car exists !\n" if defined $car;

    }

    This variable $car is eradicated, deleted, killed, destroyed.

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    35/118

    And now for something completely different....

    Basic Regular Expressions

    An introduction

    Or regex for short. These can be a little intimidating. But I'll bet you have already used some regexin your computing life so far. Have you even said "I'll have any Dutch beer ?" That's a regex whichwill match a Grolsch or Heineken, but not a Budweiser, orange juice or cheese toastie. Whatabout dir *.txt ? That's a regular expression too, listing any files ending in .txt.

    Perl's regex often look like this:

    $name=~/piper/

    That is saying "If 'piper' is inside $name, then True."

    The regular expression itself is between / / slashes, and the =~ operator assigns the target for thesearch.

    An example is called for. Run this, and answer it with 'the faq'. Then try 'my tealeaves' and see whathappens.

    print "What do you read before joining any Perl discussion ? ";chomp ($_=);

    print "Your answer was : $_\n";

    if ($_=~/the faq/) {print "Right ! Join up !\n";

    } else {print "Begone, vile creature !\n";

    }

    So here $_ is searchedfor 'the faq'. Guess what we don't need ! The =~ .This works just as well:if (/the faq/) {

    because if you don't specify a variable, then perl searches $_ by default.In this particular case, it would be better to useif ($_ eq "the faq") { as we are testing for exact matches.

    Senstivity -- regexes in touch with their inner child

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    36/118

    But what if someone enters 'The FAQ' ? It fails, because the regex is case sensitive. We can easilyfix that:

    if (/the faq/i) {

    with the /i switch, which

    specifies case-insensitivity. Now it works for all variations, such as"theFaq" and "the FAQ".

    Now you can appreciate why a regular expression is better in this situation than a simple testusing eq . As the regex searches one string for another string, a response of "I would read the FAQfirst !" will also work, because "the FAQ" will match the regex.

    Study this example just to clarify the above. Tabs and spaces have been added for aesthetic beauty:

    $_="perl for Win32"; # sets the string to besearched

    if ($_=~/perl/) { print "Found perl\n" }; # is 'perl' inside $_ ?$_ is "perl for Win32".if (/perl/) { print "Found perl\n" }; # same as the regex above.Don't need the =~ as we are testing $_if (/PeRl/) { print "Found PeRl\n" }; # this will fail becauseof case sensitivityif (/er/) { print "Found er\n" }; # this will work, becausethere is an 'er' in 'perl'if (/n3/) { print "Found n3\n" }; # this will work, becausethere is an 'n3' in 'Win32'if (/win32/) { print "Found win32\n" }; # this will fail becauseof case sensitivity

    if (/win32/i) { print "Found win32 (i)\n" }; # this will *work* becauseof case insensitivity (note the /i)

    print "Found!\n" if / /; # another way of doing it,this time looking for a space

    print "Found!!\n" unless $_!~/ /; # both these are the same, butreversing the logic with unless and !print "Found!!\n" unless !/ /; # don't do this, it willalways never not confuse nobody :-)

    # the ~ stays the same, but =is changed to ! (negation)

    $find=32; # Create some variables tosearch for$find2=" for "; # some spaces in thevariable too

    if (/$find/) { print "Found '$find'\n" }; # you can search forvariables like numbersif (/$find2/) { print "Found '$find2'\n" }; # and of course strings !

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    37/118

    print "Found $find2\n" if /$find2/; # different way to do theabove

    As you can see from the last example, you can embed a variable inthe regex too. Regular expressions could fill entire books (and they havedone, see the book critiques at http://www.perl.com/) but here are some

    usefultricks:

    Character Classes

    @names=qw(Karlson Carleon Karla Carla Karin Carina Needanotherword);

    foreach (@names) { # sets each element of @names to$_ in turn

    if (/[KC]arl/) { # this line will be changed a fewtimes in the examples below

    print "Match ! $_\n";} else {

    print "Sorry. $_\n";}

    }

    This time @names isinitialised using whitespace as a delimiter instead of a comma. qw refersto'quote words', which means split the list by words. A word ends withwhitespace(like tabs, spaces, newlines etc).

    The square brackets enclose single characters to be matched. Here either Karl or Carl mustbe in each element. It doesn't have to be two characters, and you can use more than one set.Change Line 4 in the above program to:

    if (/[KCZ]arl[sa]/) {

    matches if something begins with K, C, or Z, then arl, then either s or a. It does notmatch KCZarl.Negation is possible too, so try this :

    if (/[KCZ]arl[^sa]/) {

    which returns things beginning with K, C or Z, then arl, and then anything EXCEPT s or a. Thecaret ^ has to be the first character, otherwise it doesn't work as the negation. Having said [] defines single characters only, I should mention than these two are the same:

    /[abcdeZ]arl/;/[a-eZ]arl/;

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    38/118

    if you use a hyphen then you get the list of characters including the start and finish characters. And ifyou want to match a special character (metacharacter), you must escape it:

    /[\-K]arl/;

    matches Karl or -arl. Although the - character is representedby two characters, it is just the one

    character to match.

    Matching at specific points

    If you want to match at the end of the line, make sure a $ is the last character in the regex. This onepulls out all those names ending in a. Slot it into the example above :

    if (/a$/) {

    And there is a corresponding character, the caret ^ , which in this context matches at

    the beginning of the string. Yes, the caret also negates a character class like this [^KCZ]arl but inthis case itanchors the match to the beginning of the string.

    if (/n/i) {if (/^n/i) {

    The first one is true if the word contains an 'n' anywhere in it.The second specifies that the 'n' must be at the beginning of the stringto bematched. Use this anchor where you can, because it makes the whole regexfaster, and safer if you know what the first character must be.

    Negating the regex

    If you want to negate the entire regex change =~ to !~ (Remember ! means 'not equal to'.)

    if ($_ !~/[KC]arl/) {

    Of course, as we are testing $_this works too:if (!/[KC]arl/) {

    Returning the Match

    Now things get interesting. What if we want pull something out of a string ? So far all we have doneis test for truth, that is say yea or nay if a string matches, but not return what we found. Run this:

    $_='My email address is .';

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    39/118

    /()/i;

    print "Found it ! $1\n";

    Firstly, note the single quotes when $_

    is assigned. If there were double quotes, we'd need\@ instead of @ .Remember, double quotes "" allow variable interpolation, so Perl looks foranarray called @NetCat which does not exist.

    Secondly, look at the parens around the entire regex. If you use parens, a side effect is that the firstmatch is put into a variable called $1 . We'll get to the main effect later. The second match goesinto $2and so on. Also note that the \@ has been escaped, so perl doesn't think it is an array.Remember \ either escapes a special character, or gives a special meaning. Think of it asSuperman's telephone box. Imagine Clark Kent walking around with his magic partner Back Slash.

    Notice how we specify in the regex case-insensitivity with /i and the regex returns the case-

    sensitive string - that is, exactly what it found.

    Try the regex without parens. Then try this one:

    //i;

    You can put the parens anywhere. More or less. Now, run this :$_='My email address is .';

    //i;

    print "Found it ! $1 at $2\n";

    See, you can have more than one ! Look at the above regex. Lookseasy now, don't you think ? What about five minutes ago ? It would havelookedlike a typing mistake ! Well, there are some hairier regex to come, butyou'llhave a good barber.

    * + -- regexes become line noise

    What if we didn't know what the email address was going to be ?

    $_='My email address is .';

    print "Found it ! :$1:" if /()/i;

    When you see an ifstatement like this, read it right to left. The print statement is onlyexecuted if code onthe right of the expression is true.

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    40/118

    We'll discuss this. Firstly, we have the opening parens ( . So everything from ( to ) will be putinto $1 if the match is successful. Then the first character of what we are searching for, < . Then wehave a dot, or period . . For this regex, we can assume . matches any character at all.

    So we are now matching < followed by any character. The * means 0 or more of the previouscharacter. The regex finishes by requiring > .

    This is important. Get the basics right and all regex are easy (I read somewhere once). An examplebest illustrates the point. Slot this regex in instead:

    $_='My email address is .';

    print "Found it ! :$1:" if /()/i;

    What's happening here ?

    The regex starts, logically, at the start of the string. This doesn't mean it starts a 'M', it starts justbefore M. There is a 'nothing' between the string start and 'M'.

    The regex is searching for

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    41/118

    But, be warned. The match may be successful but your job is not done. Assuming the objective ofwas to return the email address within the angle brackets then that regex is a miserable failure.Watch for traps of this nature when regexing.

    That's * explained. Just to consolidate, a quick look at:

    $_='My email address is .';print "Match 1 worked :$1:" if /(

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    42/118

    Just add a question mark and Perl does stingy matching. Nonationalistic jokes. I have Dutch and Scottish friends I don't want tooffend.

    The Difference Between + and *

    You know what * means, namely match 0 or more. If you want to match 1 or more, then use + .The difference is important.

    $_='The number is 2200 and the day is Monday';

    ($star)=/([0-9]*)/;

    ($plus)=/([0-9]+)/;

    print "Star is '$star' and Plus is '$plus'\n";

    You'll note that $star has no value. The match wassuccessful though. It managed to match 0 or more characters from 0 to 9 atthevery start of the regex.

    The second regex with $plus worked a little better, because we are matching one or morecharacters from 0 to 9. Therefore, unless one 0 to 9 is found the match will fail. Once a 0-9 is found,the match continues as long as the next character is 0-9, then it stops.

    Now we know this, there is another way to remove an email address from within angle brackets:

    $_='My email address is !.';

    /]+)/i;

    print "Found it ! $1\n";This regex matches ]+ simplycontines matching until it finds something that fails its criteria. Just make sure you understand thedifference because it is a crucial part of regexery.

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    43/118

    Re-using the match -- \1, $1...

    Suppose we didn't know what HTML tag we had to match ? It could be B, I, EM or whatever, and wewant everything that is in between. Well, HTML container tags like B and EM have end tags whichare the same as the start tag, except for the / . So what we could do is:

    find out what is inside < > search for exactly the same tag, but with the closing / return whatever is in between.

    Can this be done ? Of course. This is perl, all things are possible. Now, remember the side effect ofparens. I promise I'll explain the primary effect at some point. If whatever is in (parens) matches, theresult is stored in a variable called $1 . So we can use which will find us < then as manyanythings (the . and * ) up to the next, not last > (the ? forces stingy matching).

    The result is stored in $1 because we used parens. Next, we need everything up to the closing tag.That's easy : (.*?) matches everything up until the next character or set of characters. And how

    exactly do we define where to stop ?

    We can use $1 even in the same regex it was found in. However, it is not referred to within a regexas $1 , but \1 .

    So we want to match which in perl code is . The / must be escaped because it isthe end of the regex, and 1 is escaped so it refers to $1 instead of matching the number 1.

    Still here ? This is what it looks like:

    $_='HTML munging time is here again !.';/(.*?)/i;

    print "Found it ! $2\n";

    If you want to know how to return all the matches above, read on.But before that:

    How to Avoid Making Mountains while EscapingSpecial Characters

    You want to match this; http://language.perl.com/faq/ . That's a real (useful) URL by the

    way. Hint. To match it, you need to do this:

    /http:\/\/language\.perl\.com\/faq\//;

    which should make the awful metaphor above clearer, if notfunnier. The slash, / , is notnormally a metacharacter but as it is being used for the regularexpressiondelimiters, it needs to be escaped. We already know that . is special.

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    44/118

    Fortunately for our eyes, Perl allows you to pick your delimiter if you prefix it with 'm' as this exampleshows. We'll use a #:

    m#http://language\.perl\.com/faq/#;Which is a huge improvement, as we change / to # .We can go further with readability by quoting everything:

    m#\Qhttp://language.perl.com/faq/\E#;The \Q escapes everythingup until \E or the regex delimiter (sowe don't really need the \E above). In this case #will not be escaped, as it delimits the regex.

    Someone once posted a question about this to the Perl-Win32-Users mailing list and I was sointrigued about this apparently undocumented trick I spent the next twenty minutes figuring it out bytrial and error, and posted a reply. Next day I found lots of messages telling the poster to read themanual because it was clearly documented. My excuse was Ididn't have the docs to hand....moral of the story - RTFM and RTF FAQs !

    Subsitution and Yet More Regex Power

    Basic changes

    Suppose you want to replace bits of a string. For example, 'us' with 'them'.

    $_='Us ? The bus usually waits for us, unless the driver forgets us.';

    print "$_\n";

    s/Us/them/; # operates on $_, otherwise you need $foo=~s/Us/them/;

    print "$_\n";

    What happens here is that the string 'Us' is searched for, andwhen a match is found it is replaced with the right side of theexpression, inthis case 'them'. Simple.

    You'll notice that only one substitution was made. To match globally use /g which runs through theentire string, changing wherever it can. Try:

    s/Us/them/g;

    which fails. This is because regexes are not, by default,case-sensitive. So:s/us/them/ig;

    would be a better bet. Now, everything is changed. A little too

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    45/118

    much, but one problem at a time. Everything you have learn about regex sofarcan be used with s/// , like parens,character classes [ ] , greedy andstingy matching and much more. Deleting things is easy too. Just specifynothing as the replacement character, like so s/Us//; .

    So we can use some of that knowledge to fix this problem. We need to make sure that a spaceprecedes the 'us'. What about:

    s/ us/them/g;

    An small improvement. The first 'Us' is now no longer changed,but one problem at a time ! We'll first consider the problem of the regexchanging 'usually' and other words with 'us' in them.

    What we are looking for is a space, then 'us', then a comma, period or space. We know how tospecify one of a number of options - the character class.

    s/ us[. ,]/them/g;

    Another tiny step. Unfortunately, that step wasn't really in theright direction, more on the slippery slope to Poor Programming Practice.Why?Because we are limiting ourselves. Suppose someone wrote ' send it to us;when we get it'.

    You can't think of all the possible permutations. It is often easier, and safer, to simply state whatmust notfollow the match. In this case, it can be anything except a letter. We can define that as a-z.So we can add that to the regex.

    s/ us[^a-z]/ them/g;

    the caret ^ negates thecharacter class, and a-z representsevery alphabet from a to z inclusive. A space has been added to thesubstitution part - as the original space was matched, it should bereplacedto maintain readability.

    \w

    What would be more useful is to use a-zA-Z instead. If we weren't using /i we'd need that. As a-zA-Z is such a common construct, Perl provides an easy shorthand:

    s/ us[^\w]/ them/g;

    The \w construct actually means 'word' - equivalent to a-zA-Z_0-9 . So we'll use that instead.

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    46/118

    To negate any construct, simply capitalise it:

    s/ us[\W]/ them/g;

    and of course we don't need the negating caret now. In fact, we don't even need the character class!

    s/ us\W/ them/g;

    So far, so good. Matching the first 'us' is going to be difficult though. Fortunately, there is an easysolution. We've seen Perl's definition of a word - \w . Between each word is a boundary. You canmatch this with \b .

    s/\bus\W/ them/g;

    that's \b followed by 'us', not 'bus' :-)

    Now, we require a word boundary before 'us'. As there is a 'nothing' at the start of the string, wehave a match. There is a space after the first 'Us', so the match is successful. You might notice an

    extra space has crept in - that's the space we added earlier. The match doesn't include the spaceany more - it matches on the word boundary, that is just before the word begins. The space doesn'tcount.

    Did you notice the final period and the comma are replaced? They are part of the match - it isthe \W that matches them. We can't avoid that. We can however put back that part of the match.

    Replacing with what was found

    s/\bus(\W)/them\1/g;

    We start with capturing whatever the \W matches, using parens. Then, we add it to the replacementstring. The capture is of course in $1 , but as it is in a regex we refer to it as \1 .

    The final problem is of course capitalising the replacement string when appropriate. Which in oldversions of the tutorial I left as an exercise to the reader, having run out of motivation. A reader bythe name of Paul Trafford duly solved the problem, and I have just inserted his excellent explanationfor the elucidation of all concerned:

    # Solution to the us/them problem...## The program works through the text assigning the# variable $1 to 'U' or 'u' for any words where this

    # letter is followed by 's' and then by non 'word'# characters. The latter is assigned to variable $2.## For each such matching occurrence, $1 is replaced by# the letter that precedes it in the alphabet using# operations 'ord' and 'chr' that return the ASCII value# of a character and the character corresponding to a# given natural number. After this 'hem' is tacked on# followed by $2, to retain the shape of the original

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    47/118

    # sentence. The '/e' switch is used for evaluation.## NOTES# 1. This solution will not replace US (short for# United States) with Them or them.#

    # 2. If a 'magical' decrement operator '--' existed for# strings then the solution could be simplified for we# wouldn't need to use the 'chr' and 'ord' operators.$_='Us ? The bus usually waits for us, unless the driver forgets us.';

    print "$_\n";

    s/\b([Uu])s(\W)/chr(ord($1)-1).hem.$2/eg;

    print "$_\n";

    An excellent solution, thanks Paul.

    There are several more constructs. We'll take a quick look at \d which means anything that is adigit, that is 0-9 . First we'll use the negated form, \D , which is anything except0-9 :

    print "Enter a number :";chop ($input=);

    if ($input=~/\D/) {print "Not a number !!!!\n";

    } else {print 'Your answer is ',$input x 3,"\n";

    }

    this checks that there are no non-number characters in $x . It's not perfect because it'll choke ondecimal points, but it's just an example. Writing your own number-checker is actually quite difficult,but it is an interesting exercise. Try it, and see how accurate yours is.

    x

    I hope you trusted me and typed the above in exactly as it is show (or pasted it), because the x is

    not a mistake, it is a feature. If you were too smart and changed it to a * or something change itback and see what it does.

    Of course, there is another way to do it :

    unless ($input=~/\d/) {print 'Your answer is ',$input x 3,"\n";

    } else {print "Not a number !!!!\n";

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    48/118

    }

    which reverses the logic with an unless statement.

    More Matching

    Assume we have:

    $_='HTML munging time is here again !.';

    and we want to find all the italic words. We know that /g will match globally, so surely this will work:

    $_='HTML munging time is here again ! What fun !';

    $match=/(.*?)/ig;

    print "$match\n";

    except it returns 1, and there were definitely two matches. The match operator returns true or false,not the number of matches. So you can test it for truth with functions like if, while,unlessIncidentally, the s/// operator does return the number of substitutions.

    To return what is matched, you need to supply a list.

    ($match) = /(.*?)/i;

    which handily puts all the first match into $match . Note that an = is used (for assignment), asopposed to =~ (to point the regex at a variable other than $_.

    The parens force a list context in this case. There is just the one element in the list, but it is still a list.The entire match will be assigned to the list, or whatever is in the parens. Try adding some parens:

    $_='HTML munging time is here again ! What fun !';

    ($word1, $word2) = /(.*?)/ig;

    print "Word 1 is $word1 and Word 2 is $word2\n";

    In the example above notice /g has been added so a global replacement is done - this means perlcarries on matching even after it finds the first match. Of course, you might not know how manymatches there will be, so you can just use an array, or any other type of list:

    $_='HTML munging time is here again ! What fun !';

    @words = /(.*?)/ig;

    foreach $word (@words) {print "Found $word\n";

    }

  • 8/3/2019 Perl Sthomasdotnet- lokesh B

    49/118

    and @words will be grown to the appropriate size for the matches. You really can supply what youlike to be assigned to:

    ($word1, @words[2..3], $last) = /(.*?)/ig;

    you'll need more ita