Omar
Omar

Reputation: 7611

How can I prevent Perl from interpreting double-backslash as single-backslash character?

How can I print a string (single-quoted) containing double-backslash \\ characters as is without making Perl somehow interpolating it to single-slash \? I don't want to alter the string by adding more escape characters also.

my $string1 = 'a\\\b';
print $string1; #prints 'a\b'

my $string1 = 'a\\\\b';
    #I know I can alter the string to escape each backslash
    #but I want to keep string as is.
print $string1; #prints 'a\\b'

#I can also use single-quoted here document
#but unfortunately this would make my code syntactically look horrible.
my $string1 = <<'EOF';
a\\b
EOF
print $string1; #prints a\\b, with newline that could be removed with chomp

Upvotes: 3

Views: 2643

Answers (3)

hobbs
hobbs

Reputation: 239980

If you are mildly crazy, and like the idea of using experimental software that mucks about with perl's internals to improve the aesthetics of your code, you can use the Syntax::Keyword::RawQuote module, on CPAN since this morning.

use syntax 'raw_quote';
my $string1 = r'a\\\b';
print $string1; # prints 'a\\\b'

Thanks to @melpomene for the inspiration.

Upvotes: 7

elcaro
elcaro

Reputation: 2297

Since the backslash interpolation happens in string literals, perhaps you could declare your literals using some other arbitrary symbol, then substitute them for something else later.

my $string = 'a!!!b';
$string =~ s{!}{\\}g;
print $string; #prints 'a\\\b'

Of course it doesn't have to be !, any symbol that does not conflict with a normal character in the string will do. You said you need to make a number of strings, so you could put the substitution in a function

sub bs {
    $_[0] =~ s{!}{\\}gr
}

my $string = 'a!!!b';
print bs($string); #prints 'a\\\b'

P.S. That function uses the non-destructive substitution modifier /r introduced in v5.14. If you are using an older version, then the function would need to be written like this

sub bs {
    $_[0] =~ s{!}{\\}g;
    return $_[0];
}

Or if you like something more readable

sub bs {
    my $str = shift;
    $str =~ s{!}{\\}g;
    return $str;
}

Upvotes: 0

hobbs
hobbs

Reputation: 239980

The only quoting construct in Perl that doesn't interpret backslashes at all is the single-quoted here document:

my $string1 = <<'EOF';
a\\\b
EOF
print $string1; # Prints a\\\b, with newline

Because here-docs are line-based, it's unavoidable that you will get a newline at the end of your string, but you can remove it with chomp.

Other techniques are simply to live with it and backslash your strings correctly (for small amounts of data), or to put them in a __DATA__ section or an external file (for large amounts of data).

Upvotes: 10

Related Questions