Adding to a number in replace

Discussion in 'Perl Misc' started by robin.corcoran@gmail.com, May 18, 2006.

  1. Guest

    Hello, I have to add to a number in a s/r. My input looks like

    Page 1
    Page 2
    Page 3

    I want

    Page 6
    Page 7
    Page 8

    Using /e I'm able to add to a number
    $string=~s/([0-9]+)/$1+1/e

    My problem comes from the fact that I don't want to globally replace
    every number. I just want to replace those with "Page #". However, the
    /e option is looking for a method when I add text to the replace
    string.

    $string=~s/Page ([0-9]+)/Page $1+1/e; yields
    "Can't call method page without a package or object.

    I tried using \Q and \E in my replace string and that doesn't help. I
    even tried using \x.. to output "Page" but that doesn't work either.

    Is what I'm trying even possible, and if so can someone nudge me in the
    right direction?

    Thanks,

    Robin
    , May 18, 2006
    #1
    1. Advertising

  2. wrote:
    > Hello, I have to add to a number in a s/r. My input looks like
    >
    > Page 1
    > Page 2
    > Page 3
    >
    > I want
    >
    > Page 6
    > Page 7
    > Page 8
    >
    > Using /e I'm able to add to a number
    > $string=~s/([0-9]+)/$1+1/e
    >
    > My problem comes from the fact that I don't want to globally replace
    > every number. I just want to replace those with "Page #". However, the
    > /e option is looking for a method when I add text to the replace
    > string.
    >
    > $string=~s/Page ([0-9]+)/Page $1+1/e; yields
    > "Can't call method page without a package or object.
    >
    > I tried using \Q and \E in my replace string and that doesn't help. I
    > even tried using \x.. to output "Page" but that doesn't work either.
    >
    > Is what I'm trying even possible, and if so can someone nudge me in the
    > right direction?


    positive lookbehind.

    use strict; use warnings;


    while ( <DATA> ) {
    s/(?<=Page)\ (\d+)/$1+1/e;
    print;
    }

    __DATA__
    Page 1
    Page 2
    it_says_BALLS_on_your forehead, May 18, 2006
    #2
    1. Advertising

  3. it_says_BALLS_on_your forehead wrote:
    > wrote:
    > > Hello, I have to add to a number in a s/r. My input looks like
    > >
    > > Page 1
    > > Page 2
    > > Page 3
    > >
    > > I want
    > >
    > > Page 6
    > > Page 7
    > > Page 8
    > >
    > > Using /e I'm able to add to a number
    > > $string=~s/([0-9]+)/$1+1/e
    > >
    > > My problem comes from the fact that I don't want to globally replace
    > > every number. I just want to replace those with "Page #". However, the
    > > /e option is looking for a method when I add text to the replace
    > > string.
    > >
    > > $string=~s/Page ([0-9]+)/Page $1+1/e; yields
    > > "Can't call method page without a package or object.
    > >
    > > I tried using \Q and \E in my replace string and that doesn't help. I
    > > even tried using \x.. to output "Page" but that doesn't work either.
    > >
    > > Is what I'm trying even possible, and if so can someone nudge me in the
    > > right direction?

    >
    > positive lookbehind.
    >
    > use strict; use warnings;
    >
    >
    > while ( <DATA> ) {
    > s/(?<=Page)\ (\d+)/$1+1/e;

    sorry, the above should be:
    s/(?<=Page\ )(\d+)/$1+1/e;


    > print;
    > }
    >
    > __DATA__
    > Page 1
    > Page 2
    it_says_BALLS_on_your forehead, May 18, 2006
    #3
  4. Guest

    wrote:
    >
    > Using /e I'm able to add to a number
    > $string=~s/([0-9]+)/$1+1/e
    >
    > My problem comes from the fact that I don't want to globally replace
    > every number. I just want to replace those with "Page #". However, the
    > /e option is looking for a method when I add text to the replace
    > string.
    >
    > $string=~s/Page ([0-9]+)/Page $1+1/e; yields
    > "Can't call method page without a package or object.



    The first way works because "$1+1" is a real expression; that is,
    you'd expect the following line of code to function properly:

    $var = $1+1;

    But replace "$1+1" with "Page $1+1" and you get an expression that
    won't compile:

    $var = Page $1+1;

    The fix is to turn "Page $1+1" into a real expression, like this:

    $var = "Page " . ($1+1);

    So rewrite your regular expression like this, and it should work
    fine:

    # (Untested:)
    $string =~ s/Page ([0-9]+)/"Page " . ($1+1)/e;

    I hope this helps, Robin.

    -- Jean-Luc
    , May 18, 2006
    #4
  5. Paul Lalli Guest

    wrote:
    > Hello, I have to add to a number in a s/r. My input looks like
    >
    > Page 1
    > Page 2
    > Page 3
    >
    > I want
    >
    > Page 6
    > Page 7
    > Page 8
    >
    > Using /e I'm able to add to a number
    > $string=~s/([0-9]+)/$1+1/e
    >
    > My problem comes from the fact that I don't want to globally replace
    > every number. I just want to replace those with "Page #". However, the
    > /e option is looking for a method when I add text to the replace
    > string.
    >
    > $string=~s/Page ([0-9]+)/Page $1+1/e; yields
    > "Can't call method page without a package or object.


    When you use /e, the replacement must be a valid Perl expression. If
    you were writing a normal perl expression, and you wanted to assign
    your replacement string to a variable, you know this wouldn't work,
    right:
    $repl = Page $1+1;
    Instead, you'd have to do:
    $repl = "Page " . ($1+1);
    And that's exactly what you have to do in the regexp:

    #!/usr/bin/perl
    use warnings;
    use strict;

    while (<DATA>){

    s/^Page (\d+)$/"Page " . ($1 + 3)/e;
    print;
    }

    __DATA__
    Page 1
    Other stuff 5
    Page 2
    Page 3

    Output:
    Page 4
    Other stuff 5
    Page 5
    Page 6


    > I tried using \Q and \E in my replace string and that doesn't help.


    I have no idea what made you think it would. \Q auto-escapes any
    regexp-special characters in a double quoted string. What does that
    have to do with your current problem?

    > I
    > even tried using \x.. to output "Page" but that doesn't work either.


    I assume you mean the /x modifier, and again I have no idea what makes
    you think this would do anything you're looking for.

    Throwing code at the program and seeing what sticks is a poor method of
    programming.

    Paul Lalli
    Paul Lalli, May 18, 2006
    #5
  6. Guest

    Thanks very much, that did it.

    Robin
    , May 18, 2006
    #6
  7. Guest

    Thanks Paul and Jean-Luc for your help.

    Robin
    , May 18, 2006
    #7
  8. Dr.Ruud Guest

    Paul Lalli schreef:

    > s/^Page (\d+)$/"Page " . ($1 + 3)/e;


    More complex looking, but still DRY-er (Don't Repeat Yourself) variants:

    s/ ^ # at BOL
    (Page[ ]) # capture "Page<space>" as $1
    (\d+) # capture 1 or more digits as $2
    /$1 . ($2 + 3)/ex; # replace captured digits

    s/ (?<=^Page[ ]) # zero-width prefix of "^Page<space>"
    (\d+) # capture 1 or more digits as $1
    /$1 + 3/ex; # replace captured digits

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, May 19, 2006
    #8
    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. Brian Blais
    Replies:
    1
    Views:
    364
    Bruno Desthuilliers
    Jun 27, 2006
  2. Greg Ewing
    Replies:
    2
    Views:
    330
    Dieter Maurer
    Jun 29, 2006
  3. Alun
    Replies:
    3
    Views:
    4,474
    Masudur
    Feb 18, 2008
  4. EK
    Replies:
    0
    Views:
    307
  5. MRAB
    Replies:
    2
    Views:
    292
    John Machin
    Jan 31, 2009
Loading...

Share This Page