Beefy Boxes and Bandwidth Generously Provided by pair Networks RobOMonk
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Regular expressions

by DDH (Initiate)
on Apr 13, 2005 at 09:19 UTC ( [id://447364]=perlquestion: print w/replies, xml ) Need Help??

This is an archived low-energy page for bots and other anonmyous visitors. Please sign up if you are a human and want to interact.

DDH has asked for the wisdom of the Perl Monks concerning the following question:

I want to check if a string contains only the caracters a-z with a regular expression but their is something wrong. This is the first time i use regular expressions. I hope someone can tell me more about it. this is my code:
if ($temp2 =~ m/[a-zA-Z]/) { $naam = $1; } else { die "Wrong input"; }

20050413 Janitored by Corion: Added formatting

Replies are listed 'Best First'.
Re: Regular expressions
by tlm (Prior) on Apr 13, 2005 at 09:26 UTC

    What you want is

    if ($temp2 =~ m/^([a-zA-Z]+)$/) { $naam = $1; } else { die "Wrong input"; }
    What you wrote matches only strings that contain the substring 'a-zA-Z' in them. You need to enclose ranges like 'A-Z' within [ ] for them to be interpreted as character classes. Also, by anchoring the regexp (with ^ and $1) you ensure that the entire string must match. The last thing is that you need that quantifier + so that one or more characters will match; without it, the only strings that will match are those consisting of a single letter.

    1Some people prefer to use \z instead of $ for the end-of-string anchor, because $ doesn't unconditionally match the end of the string; indeed, it ignores one optional trailing newline. I think of $ as basically shorthand for /\n?\z/... Well, it's more complicated than that, because the meaning of $ changes in the presence of the /m modifier, but not so for /\n?\z/... A lot of ins, a lot of outs, a lot of what-have-yous, a lot of strands to keep in the ol' duder's head...

    Update: In my original reply, I focused on the why the regexp was not matching, and failed to notice that you were using $1 later on. I fixed the regexp to reflect this. Sorry for the confusion.

    the lowliest monk

Re: Regular expressions
by Fletch (Bishop) on Apr 13, 2005 at 09:27 UTC

    You're only checking if there's at least one character matching your character class anywhere in your input. Anchor your regex: $temp2 =~ m/\A[a-zA-Z]+\z/. Read perldoc perleretut and perldoc perlre.

    And remember to use <code></code> tags next time.

Re: Regular expressions
by sh1tn (Priest) on Apr 13, 2005 at 09:28 UTC
    $temp2 =~ /^[a-zA-Z]+$/ # ^ denotes the beginning # + denotes one or more matches # $ denotes the end
    You may want to see perldoc perlre.


Re: Regular expressions
by jbware (Chaplain) on Apr 13, 2005 at 09:35 UTC
    In addition to previous mentions, you also need () around whatever you want to capture in the $1 variable.
    if ($temp2 =~ m/^([a-zA-Z]+)$/) {$naam = $1;}

    -jbWare
Re: Regular expressions
by cees (Curate) on Apr 13, 2005 at 09:43 UTC

    You already have some good answers, but here is another that just reverses your search (ie instead of searching for a-zA-Z it searches for anything that is not a-zA-Z and negates the answer):

    $temp2 !~ m/[^a-zA-Z]/

    This will return false if it finds a character that is not a-z or A-Z. The [^ ] only matches if none of the characters contained in the brackets are found.

    You could reverse your condition to make the code easier to read with this method:

    if ($temp2 =~ m/[^a-zA-Z]/) { die "Wrong input"; } else { $naam = $1; }

    - Cees

Re: Regular expressions
by dragonchild (Archbishop) on Apr 13, 2005 at 09:45 UTC
    Alternately, you can make sure that it doesn't contain characters that aren't the class.
    if ( $temp2 =~ /[^a-zA-Z]/ ) { die "Wrong input"; } else { # Do something useful }

    This is a very strong way to work. You're whitelisting and not blacklisting, which is best.

      Thanks for the information
Re: Regular expressions
by davidrw (Prior) on Apr 13, 2005 at 12:25 UTC
    lots of good answers--just want to tack on one note since OP said he's a regex first-timer.. These are all equivalent -- the /i on the end makes it case insensitive.. check the perlre man page for other modifiers (/m, /s, /x, and /g for substitutions).
    m/[a-zA-Z]/ m/[a-z]/i m/[A-Z]/i
Re: Regular expressions
by polettix (Vicar) on Apr 13, 2005 at 13:46 UTC
    You'll also enjoy YAPE::Regex::Explain by japhy reading the output of the following snippet:
    #!/usr/bin/perl use strict; use warnings; use YAPE::Regex::Explain; $\ = "\n*************\n"; # Your original print YAPE::Regex::Explain->new(qr/[a-zA-Z]/)->explain; print YAPE::Regex::Explain->new(qr/[a-zA-Z]+/)->explain; print YAPE::Regex::Explain->new(qr/([a-zA-Z]+)/)->explain; # The solution print YAPE::Regex::Explain->new(qr/^([a-zA-Z]+)$/)->explain;

    Flavio (perl -e "print(scalar(reverse('ti.xittelop@oivalf')))")

    Don't fool yourself.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://447364]
Approved by Corion
help
Sections?
Information?
Find Nodes?
Leftovers?
    Notices?
    hippoepoptai's answer Re: how do I set a cookie and redirect was blessed by hippo!
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.