Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

REGEX Match Single Digit

by spickles (Scribe)
on Aug 28, 2009 at 15:38 UTC ( [id://791941]=perlquestion: print w/replies, xml ) Need Help??

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

Monks -

I'm weak in my understanding of regex, and I've read all sorts of docs on the web this week and I still can't do this: I'd like to match a single digit, and a specific one at that. I can get $number =~ /^\d{1}$/ to differentiate between 3, 33, 333, etc. and limit to just one character. So now I want to match the digit itself and the following hasn't worked for me (to match the number 1, for example):

/^\d[1]{1}$/ /^(\d[1]{1})$/ /^\d([1]{1})$/

Replies are listed 'Best First'.
Re: REGEX Match Single Digit
by kennethk (Abbot) on Aug 28, 2009 at 15:51 UTC
    For all your regex-reference needs, check out perlre and perlretut. The pretty much cover the gamut.

    If you know your digit ahead of time, there's not need to worry about character classes. You can just use:

    /^1$/

    if you are committed to using a regular expression. If you don't know until runtime, you can use

    /^$value$/

    where you have stored your value in the variable $value. You need to remember that regular expressions are just a fancy string matching engine, so don't think about numbers as numbers, but as characters.

    However since you are not really performing flexible matches at this point but are checking equality, you should be using Equality Operators. For a string comparison, eq is the correct choice, but since you are checking numbers, you should use

    if ($_ == 1) { # Do stuff }
      kennethk -

      *SLAPS forehead*
      That simple, eh? That will match just the number 1, and not 11, or 111, etc. Lemme try it out. Does that work if I read the number one from <STDIN> and chomp the newline? Is the digit 1 now string 1?

        That will match just the number 1, and not 11, or 111, etc.

        It matches "1" and "1\n" only.

        /^1$/:

        1. At the start of the input,
        2. match "1", then
        3. optionally match "\n", then
        4. match the end of the input string.

        /^1\z/ will only match "1".

        One of the things I love about Perl is the weak typing on scalars. The digit 1 and the string "1" have roughly equivalent internal representations and which one is used depends upon the context of your call. For example the line

        print "1 line of text" + 1;

        will output the string "2". You start with a string and a number combined with the + operator. That operator takes two numbers as arguments, so perl attempts to convert the string to a number - this truncates from the first non-numeric character. We then evaluate 1+1 = 2. That two is then passed to the print subroutine, which takes a string input. Therefore, 2 is converted to "2" and output to STDOUT. Coming from a strongly-typed background, that still fills me with a profound warmth every time I do it.

Re: REGEX Match Single Digit
by toolic (Bishop) on Aug 28, 2009 at 15:59 UTC
    YAPE::Regex::Explain is a handy tool to help you understand regular expressions:
    use strict; use warnings; use YAPE::Regex::Explain; print YAPE::Regex::Explain->new('^\d[1]{1}$')->explain(); __END__ The regular expression: (?-imsx:^\d[1]{1}$) matches as follows: NODE EXPLANATION ---------------------------------------------------------------------- (?-imsx: group, but do not capture (case-sensitive) (with ^ and $ matching normally) (with . not matching \n) (matching whitespace and # normally): ---------------------------------------------------------------------- ^ the beginning of the string ---------------------------------------------------------------------- \d digits (0-9) ---------------------------------------------------------------------- [1]{1} any character of: '1' (1 times) ---------------------------------------------------------------------- $ before an optional \n, and the end of the string ---------------------------------------------------------------------- ) end of grouping ----------------------------------------------------------------------
      That's cool. Thanks. From that output, am I understanding that one of my original attempts should have worked?
        /\d1{1}/ matches any single decimal digit, "1" included, FOLLOWED BY a single "1".

        toolic's YAPE explanation makes that clear, but your original spec indicates you want a single digit (known in advance, I gather).

        Hence, /1{1}/ for a single "1" anywhere in a line, or /^1{1}$ for a line with a single "1" as its only content.

        No
Re: REGEX Match Single Digit
by biohisham (Priest) on Aug 28, 2009 at 19:08 UTC
    If you're not confident on your regular expression abilities you would not be able to use them effectively, they're a part and parcel of Perl, you'd be turning around in circles and circles when the answer lies just on the outside of it.

    Review the regular expression once again, consider the first time you studied them that it was only a getting-familiar-with time, now group them around, those that match words, those that match numbers, those that work on boundaries of words and numbers and the modifiers that extend the flexibility of these regular expressions. At the end of it look at the anchors and non-capturing groupings.

    Classifying a problem to smaller chunks can make you tackle it better. So go it spickles and cheers :).


    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://791941]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (5)
As of 2024-03-29 11:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found