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

I haven't been using perl for very long, and I'm trying to increment a string in the form of "word.word1" but when i do it, it gives me "1" For instance, if $alias contains "johnq.smith1" and I perform $alias++ then $alias becomes "1" Is it the dot that's throwing it off? How do I fix this?
my $result = $ldap->search ( base => "dc=example,dc=com", scope => "sub", filter => "mailLocalAddress=$alias\@example.com", attrs => $attrs ); if ($result->entries || grep(/\b$alias\b/i, @aliases)) { if ($alias =~ /\d$/) { $alias++; print $alias; } elsif

Replies are listed 'Best First'.
Re: incrementing strings
by Roy Johnson (Monsignor) on Mar 14, 2005 at 22:00 UTC
    perldoc perlop
    If, however, the variable has been used in only string contexts since it was set, and has a value that is not the empty string and matches the pattern /^[a-zA-Z]*[0-9]*\z/
    So yes, it's the dot.

    Caution: Contents may have been coded under pressure.
Re: incrementing strings
by ikegami (Patriarch) on Mar 14, 2005 at 22:02 UTC

    Quote perlop:

    The auto-increment operator has a little extra builtin magic to it. If you increment a variable that is numeric, or that has ever been used in a numeric context, you get a normal increment. If, however, the variable has been used in only string contexts since it was set, and has a value that is not the empty string and matches the pattern /^[a-zA-Z]*[0-9]*\z/, the increment is done as a string, preserving each character within its range, with carry:

    The "." is indeed the problem.

Re: incrementing strings
by hv (Prior) on Mar 15, 2005 at 00:52 UTC

    I think the easiest fix is to change the match for a substitution to do the increment:

    if ($alias =~ s/(\d+)$/$1 + 1/e) { print $alias; } elsif ...

    Hugo

Re: incrementing strings
by Roy Johnson (Monsignor) on Mar 15, 2005 at 00:45 UTC
    Shamefully, I didn't answer how you can fix that. Here ya go:
    if ($result->entries || grep(/\b$alias\b/i, @aliases)) { if (my ($fixed,$plusable) = $alias =~ /(.*?)([a-z]*\d+)$/i +) { ++$plusable; $alias = $fixed.$plusable; print $alias; } elsif
    Update. Ooh! Ooh!
    if ($result->entries || grep(/\b$alias\b/i, @aliases)) { if ($alias =~ s/([a-z]*\d+)$/my $x=$1; ++$x/ei) { print $alias; } elsif
    Capturing the letters is optional. If you don't, johnq.smith9 becomes johnq.smith10. Otherwise, johnq.smith9 becomes johnq.smiti0.

    Caution: Contents may have been coded under pressure.
Re: incrementing strings
by moot (Chaplain) on Mar 14, 2005 at 22:01 UTC
    Strings don't increment this way, if what you are trying to do is take
    $alias = "johnq.smith1"; $alias++;
    and turn $alias into
    "johnq.smith2"
    . What you'll need to do is save the digits into a temporary variable, increment them, then append to the digitless string:
    $alias = "johnq.smith1"; if ($alias =~ s/(\d+$)//) { $alias .= $1++; # $alias is now "johnq.smith2" }
    There are, of course, other ways to achieve this, but not via directly incrementing a string.

    Update: Ignore my response. Of course you can increment strings this way. Is it friday yet?

      s/// is the way to go, even without the period, since I don't think you want a sequence "madonna8", "madonna9", "madonnb0", "madonnb1", as string incrementing would do.
Re: incrementing strings
by ambrus (Abbot) on Mar 15, 2005 at 16:46 UTC

    In such cases, one is tempted to write this:

    $string = "johnq.smith1"; $string =~ /(\d+$)/ or die "no number"; $1++ +; print $string, $/; # WRONG
    That's however invalid, so let's do this:
    $string = "johnq.smith1"; $string =~ /(\d+$)/ or die "no number"; matc +h($string, 1)++; print $string, $/; sub match : lvalue { my $n = $_[1] || 0; substr $_[0], $-[$n], $+[$n] +- $-[$n]; }
    that doesn't have much advantage over a simple substitution of course.

    One could even create a tied array for the modifiable versions of $1, $2, ...

    { package Matched; sub TIEARRAY { bless \my$x, $_[0]; } sub FETCH { my + $n = $_[1]; substr $_, $-[$n], $+[$n] - $-[$n]; } sub STORE { my $n += $_[1]; substr($_, $-[$n], $+[$n] - $-[$n]) = $_[2]; } tie @~, Match +ed::; } local $\ = $/; $_ = "johnq.smith1"; /(\d+$)/ or die "no number"; $~[1] +++; print;
A reply falls below the community's threshold of quality. You may see it by logging in.