$string =~ /$pattern/i

$string =~ /$pattern/i

am 13.09.2007 01:53:09 von cracraft

Hi,

I am attempting to find out if a $string contains $pattern.

$string =~ /$pattern/i

normally solves it.

However, I noticed that if $pattern contains something like

(4)

and $string contains something like

ABC(4)

then

$string =~ /$pattern/i

does not work, because of the parenthesis.

I want a flat-out literal match where $string can contain any
occurrence of $pattern regardless of parenthesis.

In other words, I don't want the special characters of regular
expressions interpreted.

I could write my own pattern matcher but resist it and would
think Perl could provide the above feature.

Anybody?

--Stuart

Re: $string =~ /$pattern/i

am 13.09.2007 02:11:49 von Gunnar Hjalmarsson

cracraft@cox.net wrote:
> I am attempting to find out if a $string contains $pattern.
>
> $string =~ /$pattern/i
>
> normally solves it.
>
> However, I noticed that if $pattern contains something like
>
> (4)
>
> and $string contains something like
>
> ABC(4)
>
> then
>
> $string =~ /$pattern/i
>
> does not work, because of the parenthesis.
>
> I want a flat-out literal match where $string can contain any
> occurrence of $pattern regardless of parenthesis.
>
> In other words, I don't want the special characters of regular
> expressions interpreted.

$string =~ /\Q$pattern/i

> I could write my own pattern matcher

Really? And still not able to solve this problem?

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl

Re: $string =~ /$pattern/i

am 13.09.2007 14:50:26 von Paul Lalli

On Sep 12, 7:53 pm, cracr...@cox.net wrote:

> I want a flat-out literal match where $string can contain any
> occurrence of $pattern regardless of parenthesis.

perldoc -f index

> In other words, I don't want the special characters of regular
> expressions interpreted.

perldoc -f quotemeta


Paul Lalli

Re: $string =~ /$pattern/i

am 15.09.2007 18:04:45 von sln

On Wed, 12 Sep 2007 16:53:09 -0700, cracraft@cox.net wrote:

>Hi,
>
>I am attempting to find out if a $string contains $pattern.
>
> $string =~ /$pattern/i
>
>normally solves it.
>
>However, I noticed that if $pattern contains something like
>
> (4)
>
>and $string contains something like
>
> ABC(4)
>
>then
>
> $string =~ /$pattern/i
>
>does not work, because of the parenthesis.
>
>I want a flat-out literal match where $string can contain any
>occurrence of $pattern regardless of parenthesis.
>
>In other words, I don't want the special characters of regular
>expressions interpreted.
>
>I could write my own pattern matcher but resist it and would
>think Perl could provide the above feature.
>
>Anybody?
>
>--Stuart

Quote meta doesen't work for everything.
However, this does:

use strict;
use warnings;

my ($pat_convert);

$pat_convert = convertPatternMeta ( 'Hello...?' );
showMatchResult ($pat_convert, 'Hello...? this is a big string x');
showMatchResult ($pat_convert, 'Oh Hello x');

$pat_convert = convertPatternMeta ( '*?+' );
showMatchResult ($pat_convert, 'Hello...? this (*?+) is a big string x');
showMatchResult ($pat_convert, '*?+ and so is this');

## ------------------------------------
## Helpers
##
sub convertPatternMeta
{
my ($pattern) = shift;
my @regx_esc_codes =
(
"\\", '/', '(', ')', '[', ']', '?', '|',
'+', '.', '*', '$', '^', '{', '}', '@'
);
foreach my $tc (@regx_esc_codes) {
# code template for regex
my $xxx = "\$pattern =~ s/\\$tc/\\\\\\$tc/g;";
eval $xxx;
if ($@) {
# the compiler will show the escape char, add
# it char to @regx_esc_codes
$@ =~ s/^\s+//s; $@ =~ s/\s+$//s;
die "$@";
}
}
return $pattern;
}
##
sub showMatchResult
{
my ($pattern, $string) = @_;
my $result_txt = '';
my ($result) = $string =~ /$pattern/;
if ($result) { $result_txt = 'DOES match'}
else { $result_txt = 'Does NOT match' }
print "\nString: $string\n$result_txt\nPattern: $pattern\n";
}

Re: $string =~ /$pattern/i

am 15.09.2007 18:27:33 von Tad McClellan

sln@netherlands.co wrote:


> Quote meta doesen't work for everything.


Yes it does.


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"

Re: $string =~ /$pattern/i

am 16.09.2007 00:22:27 von sln

On Sat, 15 Sep 2007 09:04:45 -0700, sln@netherlands.co wrote:

>On Wed, 12 Sep 2007 16:53:09 -0700, cracraft@cox.net wrote:
>
>>Hi,
>>
>>I am attempting to find out if a $string contains $pattern.
>>
>> $string =~ /$pattern/i
>>
>>normally solves it.
>>
>>However, I noticed that if $pattern contains something like
>>
>> (4)
>>
>>and $string contains something like
>>
>> ABC(4)
>>
>>then
>>
>> $string =~ /$pattern/i
>>
>>does not work, because of the parenthesis.
>>
>>I want a flat-out literal match where $string can contain any
>>occurrence of $pattern regardless of parenthesis.
>>
>>In other words, I don't want the special characters of regular
>>expressions interpreted.
>>
>>I could write my own pattern matcher but resist it and would
>>think Perl could provide the above feature.
>>
>>Anybody?
>>
>>--Stuart
>
>Quote meta doesen't work for everything.
>However, this does:
>
>use strict;
>use warnings;
>
>my ($pat_convert);
>
>$pat_convert = convertPatternMeta ( 'Hello...?' );
>showMatchResult ($pat_convert, 'Hello...? this is a big string x');
>showMatchResult ($pat_convert, 'Oh Hello x');
>
>$pat_convert = convertPatternMeta ( '*?+' );
>showMatchResult ($pat_convert, 'Hello...? this (*?+) is a big string x');
>showMatchResult ($pat_convert, '*?+ and so is this');
>
>## ------------------------------------
>## Helpers
>##
>sub convertPatternMeta
>{
> my ($pattern) = shift;
> my @regx_esc_codes =
> (
> "\\", '/', '(', ')', '[', ']', '?', '|',
> '+', '.', '*', '$', '^', '{', '}', '@'
> );
> foreach my $tc (@regx_esc_codes) {
> # code template for regex
> my $xxx = "\$pattern =~ s/\\$tc/\\\\\\$tc/g;";
> eval $xxx;
> if ($@) {
> # the compiler will show the escape char, add
> # it char to @regx_esc_codes
> $@ =~ s/^\s+//s; $@ =~ s/\s+$//s;
> die "$@";
> }
> }
> return $pattern;
>}
>##
>sub showMatchResult
>{
> my ($pattern, $string) = @_;
> my $result_txt = '';
> my ($result) = $string =~ /$pattern/;
> if ($result) { $result_txt = 'DOES match'}
> else { $result_txt = 'Does NOT match' }
> print "\nString: $string\n$result_txt\nPattern: $pattern\n";
>}
>

Just a note about quotemeta, the so called \Q...\E form to use in rexp's.

If you notice in the code above, in the @regx_esc_codes array, the first element is
"\\". And this line here
my $xxx = "\$pattern =~ s/\\$tc/\\\\\\$tc/g;";
has quite a few "\\\\\\" in it.

You will notice that the combination properly escapes all literal '\' intended in the regular
expression. This is something "\Q.....\E" can't do, because its a 1-liner. Its a 1 liner
because of speed, the anything NOT in a character class, will be escaped. The liner is not
valid and it is documented here:

"perlre.html:

Beware that if you put literal backslashes (those not inside interpolated variables) between \Q and \E,
double-quotish backslash interpolation may lead to confusing results. If you need to use literal backslashes within \Q...\E,
consult Gory details of parsing quoted constructs in the perlop manpage."

I wen't the extra mile and did it properly, unfortunately 1-liners exist in Perl constructs.
The proliferation of references to \Q in the documentation is extrodinary considering this caveat is only mentioned once.
Above you can see why. This is not something simple to do if you wan't to do it right!

I strongly suggest you use the above function.

Re: $string =~ /$pattern/i

am 16.09.2007 00:48:14 von sln

On Sat, 15 Sep 2007 16:27:33 GMT, Tad McClellan wrote:

>sln@netherlands.co wrote:
>
>
>> Quote meta doesen't work for everything.
>
>
>Yes it does.

No it does not!

Re: $string =~ /$pattern/i

am 16.09.2007 01:19:55 von xhoster

Tad McClellan wrote:
> sln@netherlands.co wrote:
>
> > Quote meta doesen't work for everything.
>
> Yes it does.

I tried to weed my garden with it, and I'm not getting anywhere.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.

Re: $string =~ /$pattern/i

am 16.09.2007 03:34:53 von Petr Vileta

Tad McClellan wrote:
> sln@netherlands.co wrote:
>
>
>> Quote meta doesen't work for everything.
>
>
> Yes it does.

I don't know what version of Perl you use but in my Perl 5.6.1 quotemeta
sometime return curious results ;-)

print quotemeta('This is a string');
>This\ is\ a\ string

By me the space (0x20h) is not need to escape.
--

Petr Vileta, Czech republic
(My server rejects all messages from Yahoo and Hotmail. Send me your mail
from another non-spammer site please.)

Re: $string =~ /$pattern/i

am 17.09.2007 13:16:45 von hjp-usenet2

On 2007-09-16 01:34, Petr Vileta wrote:
> Tad McClellan wrote:
>> sln@netherlands.co wrote:
>>> Quote meta doesen't work for everything.
>>
>> Yes it does.
>
> I don't know what version of Perl you use but in my Perl 5.6.1 quotemeta
> sometime return curious results ;-)
>
> print quotemeta('This is a string');
>>This\ is\ a\ string
>
> By me the space (0x20h) is not need to escape.

The space must be escaped if used in a regexp with the /x modifier.
And escaping doesn't hurt otherwise, so this is not an example where
quotemeta "doesn't work".

hp

--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hjp@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"

Re: $string =~ /$pattern/i

am 18.09.2007 03:35:19 von Tad McClellan

Petr Vileta wrote:
> Tad McClellan wrote:
>> sln@netherlands.co wrote:
>>
>>
>>> Quote meta doesen't work for everything.
>>
>>
>> Yes it does.
>
> I don't know what version of Perl you use


That's OK, as it is not relevant.


> but in my Perl 5.6.1 quotemeta
> sometime return curious results ;-)
>
> print quotemeta('This is a string');
>>This\ is\ a\ string
>
> By me the space (0x20h) is not need to escape.


Errr, then don't call quotemeta on it!


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"

Re: $string =~ /$pattern/i

am 18.09.2007 14:32:20 von Petr Vileta

Tad McClellan wrote:
> Petr Vileta wrote:
>> print quotemeta('This is a string');
>>> This\ is\ a\ string
>>
>> By me the space (0x20h) is not need to escape.
>
>
> Errr, then don't call quotemeta on it!

This was be an example. In real script I mean something like
my $variable = myfunction(quotemeta($ARGV[0]));

where myfunction() need to get escaped string as parameter but escaped space
is nonsese.
Now I realise it as
my $arg = quotemeta($ARGV[0]);
$arg =~ s/\\\x20/ /g;
my $variable = myfunction($arg);

Know you better way?
--

Petr Vileta, Czech republic
(My server rejects all messages from Yahoo and Hotmail. Send me your mail
from another non-spammer site please.)

Re: $string =~ /$pattern/i

am 19.09.2007 04:05:43 von Tad McClellan

Petr Vileta wrote:
> Tad McClellan wrote:
>> Petr Vileta wrote:
>>> print quotemeta('This is a string');
>>>> This\ is\ a\ string
>>>
>>> By me the space (0x20h) is not need to escape.
>>
>>
>> Errr, then don't call quotemeta on it!
>
> This was be an example. In real script I mean something like
> my $variable = myfunction(quotemeta($ARGV[0]));
>
> where myfunction() need to get escaped string as parameter but escaped space
> is nonsese.
> Now I realise it as
> my $arg = quotemeta($ARGV[0]);
> $arg =~ s/\\\x20/ /g;
> my $variable = myfunction($arg);
>
> Know you better way?


Sure. The first sentence of its documentation says:

Returns the value of EXPR with all non-"word" characters backslashed.

If you want all non-"word" characters except space backslashed,
then write a s/// that does that instead:

$arg =~ s/([^\w ])/\\$1/g;


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"