Regex gurus question

Discussion in 'Perl Misc' started by Joe Cosby, Oct 7, 2004.

  1. Joe Cosby

    Joe Cosby Guest

    I have a string which will always contain a letter followed by
    numbers, eg "x12345"

    I want to take the numbers and put them in another variable.

    So I do this:

    $test = "x12345";

    $_ = $test;
    m/(\d+)/;
    $justTheNumbers = $1;

    print "justTheNumbers is $justTheNumbers\n";


    and that works, $justTheNumbers is "12345", which is what I want.

    The three-line way I do it seems retarded to me though. Is there a
    simpler way to do it?

    I mean, something that would occur more or less naturally to somebody
    more familiar with Perl and Regex? I suppose there's always some
    simpler way to do anything ... it seems like I must be missing
    something obvious though.



    --
    Joe Cosby
    http://joecosby.com/
    YOU can be more like "Bob" than you are now!

    http://www.subgenius.com
     
    Joe Cosby, Oct 7, 2004
    #1
    1. Advertising

  2. Joe Cosby wrote:
    > I have a string which will always contain a letter followed by
    > numbers, eg "x12345"
    >
    > I want to take the numbers and put them in another variable.
    >
    > So I do this:
    >
    > $test = "x12345";
    >
    > $_ = $test;
    > m/(\d+)/;
    > $justTheNumbers = $1;
    >
    > print "justTheNumbers is $justTheNumbers\n";
    >
    > and that works, $justTheNumbers is "12345", which is what I want.
    >
    > The three-line way I do it seems retarded to me though. Is there a
    > simpler way to do it?


    You can do it in one step:

    ($justTheNumbers) = $test =~ /(\d+)/;

    Or, if the only thing you need to do is cutting off the first character:

    $justTheNumbers = substr $test, 1;

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Oct 7, 2004
    #2
    1. Advertising

  3. Joe Cosby <> wrote:

    > Subject: Regex gurus question

    ^^^^^

    Many people will take offense at your attempt to trick them into
    reading your article.

    Some people will never see your post because so many others
    have tricked them by claiming the need a guru when all they
    need is straight-forward code that they have killfiled all
    articles that contain "guru".

    Have you seen the Posting Guidelines that are posted here frequently?


    > I want to take the numbers and put them in another variable.



    You can do that by putting the m// in list context, read up on
    the m// operator in

    perldoc perlop


    > m/(\d+)/;
    > $justTheNumbers = $1;



    You should never use the dollar-digit variables unless you have
    first ensured that the match *succeeded*.

    if ( m/(\d+)/ ) {
    $justTheNumbers = $1;
    }


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Oct 7, 2004
    #3
  4. Joe Cosby

    Eric Bohlman Guest

    Joe Cosby <http://joecosby.com/code/mail.pl> wrote in
    news::

    >
    > I have a string which will always contain a letter followed by
    > numbers, eg "x12345"


    s/will/is supposed to/;

    Good programmers never say "always" or "never." hehehe. Unless you do
    only trivial programming, Mr. Murphy is going to pay you several visits.
    You need to get in the habit of making your habitat unattractive to him.

    > I want to take the numbers and put them in another variable.
    >
    > So I do this:
    >
    > $test = "x12345";
    >
    > $_ = $test;
    > m/(\d+)/;
    > $justTheNumbers = $1;


    The big problem here (other than the awkwardness of the code) is that if
    Mr. Murphy does show up at your door, $justTheNumbers will contain a value
    that might *look* OK, but really isn't. For example, if you got a string
    with *no* numbers in it, $justTheNumbers would get the numbers from the
    last good string instead. If you got a string like "x12a345" it would get
    "12" which is misleading.

    A general rule is that if you're using capturing parentheses, do *not* make
    use of the $digit variables unless you've actually tested to make sure the
    match succeeded. Note that a list assignment from a match, as in Gunnar's
    first solution, takes care of this; if the match fails, the result will be
    undef rather than junk.

    The philosophy of "defensive programming" suggests that you should write

    ($justTheNumbers) = $test =~ /^[[:alpha:]](/d+)$/ or die "unexpected format
    in \$test: [$test]";

    It may *look* like a lot of extra effort, but scores of programmers have
    found that the few extra minutes of coding that such techniques entail
    saved them many *hours* of time wasted tracking down subtle bugs.

    I'll admit, though, that Gunnar's second solution (sloppier, but at least
    it will result in an empty string if there are no digits) was the first
    thing that came to my mind.
     
    Eric Bohlman, Oct 7, 2004
    #4
  5. Joe Cosby

    Joe Cosby Guest

    On Thu, 07 Oct 2004 01:25:41 +0200, Gunnar Hjalmarsson
    <> wrote:

    >Joe Cosby wrote:
    >> I have a string which will always contain a letter followed by
    >> numbers, eg "x12345"
    >>
    >> I want to take the numbers and put them in another variable.
    >>
    >> So I do this:
    >>
    >> $test = "x12345";
    >>
    >> $_ = $test;
    >> m/(\d+)/;
    >> $justTheNumbers = $1;
    >>
    >> print "justTheNumbers is $justTheNumbers\n";
    >>
    >> and that works, $justTheNumbers is "12345", which is what I want.
    >>
    >> The three-line way I do it seems retarded to me though. Is there a
    >> simpler way to do it?

    >
    >You can do it in one step:
    >
    > ($justTheNumbers) = $test =~ /(\d+)/;
    >
    >Or, if the only thing you need to do is cutting off the first character:
    >
    > $justTheNumbers = substr $test, 1;


    Thanks, much appreciated.


    --
    Joe Cosby
    http://joecosby.com/
    "The ministry of communication is duty-bound to make the use of the
    Internet impossible." - Taliban leader Mullah Mohammad Omar
     
    Joe Cosby, Oct 7, 2004
    #5
  6. Joe Cosby

    Tore Aursand Guest

    On Wed, 06 Oct 2004 16:10:18 -0700, Joe Cosby wrote:
    > I have a string which will always contain a letter followed by
    > numbers, eg "x12345"
    >
    > I want to take the numbers and put them in another variable.
    >
    > So I do this:
    >
    > $test = "x12345";
    >
    > $_ = $test;
    > m/(\d+)/;
    > $justTheNumbers = $1;
    >
    > print "justTheNumbers is $justTheNumbers\n";
    >
    > and that works, $justTheNumbers is "12345", which is what I want.
    >
    > The three-line way I do it seems retarded to me though. Is there a
    > simpler way to do it?


    You could easily write what you have written in only one line;

    ( $justTheNumbers ) = $test =~ m/(\d+)/;

    However, why use a regular expression at all? If you are _sure_ that the
    string always will begin with only one character, you could use 'substr';

    $justTheNumbers = substr( $test, 1 );


    --
    Tore Aursand <>
    "Software is like sex: It's better when it's free." (Linus Torvalds)
     
    Tore Aursand, Oct 7, 2004
    #6
  7. Joe Cosby

    Shawn Corey Guest

    Eric Bohlman wrote:
    > The philosophy of "defensive programming" suggests that you should write
    >
    > ($justTheNumbers) = $test =~ /^[[:alpha:]](/d+)$/ or die "unexpected format
    > in \$test: [$test]";
    >
    > It may *look* like a lot of extra effort, but scores of programmers have
    > found that the few extra minutes of coding that such techniques entail
    > saved them many *hours* of time wasted tracking down subtle bugs.
    >


    I guess I'm a sloppy programmer. I would have written it as:

    ( my $just_digits = $test ) =~ s/\D//g;

    I would put the test for correct format, or for any input validation
    immediately after the input is received. Extra validation during
    processing then becomes redundant. Having said that, validation for such
    things as range will have to be done after this statement. So there is
    an exception to every guideline.

    --- Shawn
     
    Shawn Corey, Oct 7, 2004
    #7
  8. Shawn Corey wrote:
    > Eric Bohlman wrote:
    >
    >> The philosophy of "defensive programming" suggests that you should write
    >>
    >> ($justTheNumbers) = $test =~ /^[[:alpha:]](/d+)$/ or die "unexpected
    >> format in \$test: [$test]";
    >>
    >> It may *look* like a lot of extra effort, but scores of programmers
    >> have found that the few extra minutes of coding that such techniques
    >> entail saved them many *hours* of time wasted tracking down subtle bugs.

    >
    > I guess I'm a sloppy programmer. I would have written it as:
    >
    > ( my $just_digits = $test ) =~ s/\D//g;


    That will work fine if the OP's actual data is the same as the example he
    presented ($test = "x12345";) however if the actual data looks something like
    "x12345 y12345 z12345" then that will not produce a correct result.


    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Oct 7, 2004
    #8
  9. Joe Cosby

    Shawn Corey Guest

    John W. Krahn wrote:

    > That will work fine if the OP's actual data is the same as the example
    > he presented ($test = "x12345";) however if the actual data looks
    > something like "x12345 y12345 z12345" then that will not produce a
    > correct result.
    >
    >
    > John


    But "x12345a" could also create problems. As I said, input validation
    would be done before processing. By this point in the program, $test
    will have valid data.

    --- Shawn
     
    Shawn Corey, Oct 7, 2004
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alex
    Replies:
    6
    Views:
    2,207
    John Saunders
    Aug 26, 2003
  2. George Copeland

    Question for Java Gurus

    George Copeland, May 17, 2004, in forum: Java
    Replies:
    44
    Views:
    1,221
    P.Hill
    May 25, 2004
  3. Dirk McCormick
    Replies:
    2
    Views:
    482
  4. Replies:
    3
    Views:
    781
    Reedick, Andrew
    Jul 1, 2008
  5. advice please wireless 802.11 on RH8

    Dear gurus how can I extract an ARRAY from a scalar regex-wise

    advice please wireless 802.11 on RH8, May 9, 2008, in forum: Perl Misc
    Replies:
    5
    Views:
    84
    Uri Guttman
    May 10, 2008
Loading...

Share This Page