15.2. Manipulating a Substring with substr
$part = substr($string, $initial_position, $length);
It takes three arguments: a string value, a zero-based initial position (like the return value of index), and a length for the substring. The return value is the substring:
my $mineral = substr("Fred J. Flintstone", 8, 5); # gets "Flint" my $rock = substr "Fred J. Flintstone", 13, 1000; # gets "stone"
As you may have noticed in the previous example, if the requested length (1000 characters, in this case) would go past the end of the string, there's no complaint from Perl, but you simply get a shorter string than you might have. But if you want to be sure to go to the end of the string, however long or short it may be, just omit that third parameter (the length), like this:
my $pebble = substr "Fred J. Flintstone", 13; # gets "stone"
The initial position of the substring in the larger string can be negative, counting from the end of the string (that is, position -1 is the last character). In this example, position -3 is three characters from the end of the string, which is the location of the letter i:
my $out = substr("some very long string", -3, 2); # $out gets "in"
my $long = "some very very long string"; my $right = substr($long, index($long, "l") );
Now here's something really cool: The selected portion of the string can be changed if the string is a variable:
my $string = "Hello, world!"; substr($string, 0, 5) = "Goodbye"; # $string is now "Goodbye, world!"
As you see, the assigned (sub)string doesn't have to be the same length as the substring it's replacing. The string's length is adjusted to fit. Or if that wasn't cool enough to impress you, you could use the binding operator (=~) to restrict an operation to work with just part of a string. This example replaces fred with barney wherever possible within just the last twenty characters of a string:
substr($string, -20) =~ s/fred/barney/g;
To be completely honest, we've never actually needed that functionality in any of our own code, and chances are that you'll never need it either. But it's nice to know that Perl can do more than you'll ever need, isn't it?
Much of the work that substr and index do could be done with regular expressions. Use those where they're appropriate. But substr and index can often be faster, since they don't have the overhead of the regular expression engine: they're never case-insensitive, they have no metacharacters to worry about, and they don't set any of the memory variables.
Besides assigning to the substr function (which looks a little weird at first glance, perhaps), you can also use substr in a slightly more traditional manner with the four-argument version, in which the fourth argument is the replacement substring:
my $previous_value = substr($string, 0, 5, "Goodbye");
Copyright © 2002 O'Reilly & Associates. All rights reserved.