Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > matching string literals

Reply
Thread Tools

matching string literals

 
 
Morfys
Guest
Posts: n/a
 
      02-01-2011
Hello,

I would like to able to match strings with several uninterpreted
characters (for instance, "/", "-", "(", and "=").

Ideally, I would like to not have to escape each of these characters
with a "\", as I have many different strings with many special
characters to try to match.

Is there any way to force the search of a string literally?

I have tried m/\Q $string \E/, but the issue is that $string can
contain "/", which perl interprets rather than taking it literally.

Thank you in advance.

 
Reply With Quote
 
 
 
 
sln@netherlands.com
Guest
Posts: n/a
 
      02-01-2011
On Tue, 1 Feb 2011 15:45:55 -0800 (PST), Morfys <(E-Mail Removed)> wrote:

>Hello,
>
>I would like to able to match strings with several uninterpreted
>characters (for instance, "/", "-", "(", and "=").
>
>Ideally, I would like to not have to escape each of these characters
>with a "\", as I have many different strings with many special
>characters to try to match.
>
>Is there any way to force the search of a string literally?
>
>I have tried m/\Q $string \E/, but the issue is that $string can
>contain "/", which perl interprets rather than taking it literally.
>
>Thank you in advance.


Try m{\Q $string \E}.
As a side note, $string has spaces around it that is literal in the
regex unless m//x

-sln
 
Reply With Quote
 
 
 
 
Jürgen Exner
Guest
Posts: n/a
 
      02-02-2011
Morfys <(E-Mail Removed)> wrote:
>I would like to able to match strings with several uninterpreted
>characters (for instance, "/", "-", "(", and "=").
>
>Ideally, I would like to not have to escape each of these characters
>with a "\", as I have many different strings with many special
>characters to try to match.
>
>Is there any way to force the search of a string literally?


There is standard function that probably does exactly what you are
asking for, see
perldoc -f index

jue
 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      02-02-2011
On Tue, 01 Feb 2011 15:57:04 -0800, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

>On Tue, 1 Feb 2011 15:45:55 -0800 (PST), Morfys <(E-Mail Removed)> wrote:
>
>>Hello,
>>
>>I would like to able to match strings with several uninterpreted
>>characters (for instance, "/", "-", "(", and "=").
>>
>>Ideally, I would like to not have to escape each of these characters
>>with a "\", as I have many different strings with many special
>>characters to try to match.
>>
>>Is there any way to force the search of a string literally?
>>
>>I have tried m/\Q $string \E/, but the issue is that $string can
>>contain "/", which perl interprets rather than taking it literally.
>>
>>Thank you in advance.

>
>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

 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      02-02-2011
On Wed, 02 Feb 2011 12:50:33 -0800, (E-Mail Removed) wrote:

>On Tue, 01 Feb 2011 15:57:04 -0800, (E-Mail Removed) wrote:
>
>----------
>
>Quotemeta does this:
> (my $tmp_str = $string) =~ s/(^\W)/\\$1/g;

^^^^^^
(my $tmp_str = $string) =~ s/(\W)/\\$1/g;
or
(my $tmp_str = $string) =~ s/([^\w])/\\$1/g;

Typo's.

-sln
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Help with Pattern matching. Matching multiple lines from while reading from a file. Bobby Chamness Perl Misc 2 05-03-2007 06:02 PM
compilation error: "error: no matching function for call to 'String::String(String)' =?ISO-8859-1?Q?Martin_J=F8rgensen?= C++ 5 05-06-2006 03:48 PM
Java: byte literals and short literals John Goche Java 8 01-17-2006 11:12 PM
String literals in Java Harri Pesonen Java 59 06-02-2004 08:00 PM
Pattern matching : not matching problem Marc Bissonnette Perl Misc 9 01-13-2004 05:52 PM



Advertisments