views:

3754

answers:

3

If I had:

$foo= "12."bar bar bar"|three";

how would I insert in the text ".." after the text 12. in the variable?

A: 

If you want to use double quotes in a string in Perl you have two main options:

$foo = "12.\"bar bar bar\"|three";

or:

$foo = '12."bar bar bar"|three';

The first option escapes the quotes inside the string with backslash.

The second option uses single quotes. This means the double quotes are treated as part of the string. However, in single quotes everything is literal so $var or @array isn't treated as a variable. For example:

$myvar = 123;
$mystring = '"$myvar"';
print $mystring;
> "$myvar"

But:

$myvar = 123;
$mystring = "\"$myvar\"";
print $mystring;
> "123"

There are also a large number of other Quote-like Operators you could use instead.

Dave Webb
A: 

$foo = "12.\"bar bar bar\"|three";
$foo =~s/12\./12\.\.\./;
print $foo; # results in 12...\"bar bar bar\"|three"
Geo
+9  A: 

Perl allows you to choose your own quote delimiters. If you find you need to use a double quote inside of an interpolating string (i.e. "") or single quote inside of a non-interpolating string (i.e. '') you can use a quote operator to specify a different character to act as the delimiter for the string. Delimiters come in two forms: bracketed and unbracketed. Bracketed delimiters have different beginning and ending characters: [], {}, (), [], and <>. All other characters* are available as unbracketed delimiters.

So your example could be written as

$foo = qq(12."bar bar bar"|three);

Inserting text after "12." can be done many ways (TIMTOWDI). A common solution is to use a substitution to match the text you want to replace.

$foo =~ s/^(12[.])/$1../;

the ^ means match at the start of the sting, the () means capture this text to the variable $1, the 12 just matches the string "12", and the [] mean match any one of the characters inside the brackets. The brackets are being used because . has special meaning in regexes in general, but not inside a character class (the []). Another option to the character class is to escape the special meaning of . with \, but many people find that to be uglier than the character class.

$foo =~ s/^(12\.)/$1../;

Another way to insert text into a string is to assign the value to a call to substr. This highlights one of Perl's fairly unique features: many of its functions can act as lvalues. That is they can be treated like variables.

substr($foo, 3, 0) = "..";

If you did not already know where "12." exists in the string you could use index to find where it starts, length to find out how long "12." is, and then use that information with substr.

Here is a fully functional Perl script that contains the code above.

#!/usr/bin/perl

use strict;
use warnings;

my $foo = my $bar = qq(12."bar bar bar"|three); 

$foo =~ s/(12[.])/$1../;

my $i = index($bar, "12.") + length "12.";
substr($bar, $i, 0) = "..";

print "foo is $foo\nbar is $bar\n";

* all characters except whitespace characters (space, tab, carriage return, line feed, vertical tab, and formfeed) that is

Chas. Owens
If you keep writing answers this detailed (and given how busy you already are on the Perl Beginners mail list), I doubt you'll get any work done at all. Luckily, SO doesn't have a big volume of Perl questions...
Telemachus
Heh, you may notice may attendance at PB waxes and wanes. I tend to go to PB when I either have little to do, or I am so frustrated I can't get any real work done anyway. All of this is part of my training myself to be a trainer (which is why I go for the hyper-detailed answers).
Chas. Owens
That's a heck of an answer.
SquareCog
I am surprised that no one has called me on "All other characters are available as unbracketed delimiters." Whitespace characters are not valid delimiters.
Chas. Owens
Odd fact that I discovered while testing to make sure it was only whitespace characters that aren't valid delimiters: backspace and delete are valid delimiters. This gives me a new idea for Acme::Bleach.
Chas. Owens
well, thanks for your extremely lengthy answer which surprisingly made perfect sense to me.
Mr. Vile