Try m{\Q $string \E}.
As a side note, $string has spaces around it that is literal in the
regex unless m//x
To correct myself, '/' has no special meaning inside of regex's,
its taken as a literal.
The problem is that as you see it, '/' is being used as a delimeter
that Perl, when you say m//, uses to parse out the regex.
Either s/// or m//. Any character can be used as the delimeter.
Example:
m/ $string / parses out ' $string '
m# $string /# parses out ' $string /'
m/ $string/ / syntax error, one too many delimeters '/'
The regex is parsed, variable interpolation is done,
then the regex is evaluated for proper syntax.
But, it is parsed first. So any character in $string used as a
delimeter before parsing is not considered a parsing character
because parsing is already done.
You can use different characters for the delimeter, but some
delimeter characters have special meaning to the parser.
See perlop manpage for m// and also quote like operators.
quotemeta EXPR:
-----------------
This documentation (perlfunc man page), says:
"Returns the value of EXPR with all non-"word" characters backslashed."
e.g. NOT /[A-Za-z_0-9]/
Why do they do this? To take away special escape characters and
the possibility of quantifier construct-punctuation.
Unfortunately, they ruin the entire string if you actually want
any of these (especially the escape character) in there. The net result
is that everything in the string is innoculated, but this throws
out the baby with the bathwater.
The best thing to do is learn what the perl special characters are,
ie: its metacharacters, then do your own escaping where needed.
----------
Quotemeta does this:
(my $tmp_str = $string) =~ s/(^\W)/\\$1/g;
Since quotemeta() escapes all non-word characters, you could exclude
some chararacters from being escaped with a negative class.
s/([^\W\\])/\\$1/g;
For instance [^\W\\] will escaped all non-words but won't escape
'\' itself. So, you could run your $string through this:
(my $tmp_str = $string) =~ s/([^\W\\])/\\$1/g;
Add any other characters to the negative class you don't want to be escaped.
You could also create a custom character property class using the
\p{} or \P{} construct. In that class you could just define the metachars
then use that to escape just those characters.
Like,
(my $tmp_str = $string) =~ s/(\p{InMyclass})/\\$1/g;
or possibly without the '\' escape character itself,
(my $tmp_str = $string) =~ s/([^\P{InMyclass}\\])/\\$1/g;$string =~ /
More often then not, if searching for a literal '\n' or other literal
control characters, the '\' is not desired to be escaped.
---------
Here is some code you could test out that illustrates these options...
Wether or not the \p{} construct invokes some mega unicode database
I'm not sure of, or if there is a performance hit. If it is, its just
a one time event.
Cheers,
-sln
---------
use warnings;
use strict;
sub InMeta {
# {}[]()^$.|*+?\
return <<END;
7b
7d
5b
5d
28
29
5e
24
2e
7c
2a
2b
3f
5c
END
}
my $rx = q!{}[]()^$.|*+?\<--meta, word-->ABCabc123_, newline \n!;
# Compressed:
# (my $rx_quoted_meta1 = $rx) =~ s/(\p{InMeta})/\\$1/g;
# (my $rx_quoted_meta2 = $rx) =~ s/([^\P{InMeta}\\])/\\$1/g;
# (my $rx_quoted_all1 = $rx) =~ s/(\W)/\\$1/g;
# (my $rx_quoted_all2 = $rx) =~ s/([^\w\\])/\\$1/g;
(my $rx_quoted_meta1 = $rx) =~ s/
(
\p{InMeta} # Custom meta class
)
/\\$1/xg;
(my $rx_quoted_meta2 = $rx) =~ s/
(
[^ # Negative class
\P{InMeta} # not meta class (result = include meta chars)
\\ # '\' escapes (exclude)
]
)
/\\$1/xg;
(my $rx_quoted_all1 = $rx) =~ s/(\W)/\\$1/xg;
(my $rx_quoted_all2 = $rx) =~ s/
(
[^ # Negative class
\w # words (exclude)
\\ # '\' escapes (exclude)
]
)
/\\$1/xg;
my $rx_Q = quotemeta $rx;
print "Original:\n$rx\n\n";
print "Quoted meta:\n$rx_quoted_meta1\n\n";
print "** Quoted meta, not \\:\n$rx_quoted_meta2\n\n";
print "Quoted all, not words:\n$rx_quoted_all1\n\n";
print "Quotemeta function:\n$rx_Q\n\n";
print "Quoted all, not words, not \\:\n$rx_quoted_all2\n\n";
__END__
Original:
{}[]()^$.|*+?\<--meta, word-->ABCabc123_, newline \n
Quoted meta:
\{\}\[\]\(\)\^\$\.\|\*\+\?\\<--meta, word-->ABCabc123_, newline \\n
** Quoted meta, not \:
\{\}\[\]\(\)\^\$\.\|\*\+\?\<--meta, word-->ABCabc123_, newline \n
Quoted all, not words:
\{\}\[\]\(\)\^\$\.\|\*\+\?\\\<\-\-meta\,\ word\-\-\>ABCabc123_\,\ newline\ \\n
Quotemeta function:
\{\}\[\]\(\)\^\$\.\|\*\+\?\\\<\-\-meta\,\ word\-\-\>ABCabc123_\,\ newline\ \\n
Quoted all, not words, not \:
\{\}\[\]\(\)\^\$\.\|\*\+\?\\<\-\-meta\, word\-\-\>ABCabc123_\, newline \n