R. Joseph Newton wrote: > Rob Dixon wrote: > > > Hi Scott, Francesco. > > > > Scott R. Godin wrote: > > > Francesco Del Vecchio wrote: > > > > > > > suppose this: > > > > ====================================== > > > > $string 'I saw Roger and I said :roger? what the @*$!'; > > > > > > > > $var1 = "roger? what the @*$!"; > > > > $var2 = "Hi roger...nice to meet you"; > > > > > > > > $string=~ s/$var1/$var2/; > > > > ======================================= > > > > > > > > I'm having problems....due (i suppose) to the special chars in > > > > the $var1 string the s/// don't match anything. > > > > What can I do to? > > > > > > s{\Q$var1\E}{$var2} is usually what you want, except that may very > > > well 'quote' out the $ in $var. > > > > I guess you mean $var2? The replacement expression will > > only be interpolated once. Any variable names embedded in the > > contents of $var2 will be copied verbatim. > > > > > I suspect what you really want is > > > > > > $var1 = qr{roger? what the @*$!}; > > > > This won't work, I'm afraid. The $! will be interpolated > > unless the delimiters are single-quotes: > > > > print (my $var1 = qr{roger? what the @*$!}); > > > > output > > > > (?-xism:roger? what the @*) > > > > > ( perldoc -f qr ) (perldoc perlre) and (perldoc perlop) for more > > > details. > > > > Maybe what is wanted is: > > > > $var1 = quotemeta q{roger? what the @*$!}; > > > > which is the equivalent of the \Q...\E construct, but > > applicable to an existing string. > > > > HTH, > > > > Rob > > Hi Rob, > > Well, almost there. FWIW, the poison characters are the regex > control characters [?*$]. The at symbol and exclamation mark worked > fine.
Context, context, context! In the statement my $var1 = qr{roger? what the @*$!}; the string is in 'double-quote' context, ans so will attempt to expand the scalar $! (the latest C library errno) which in my example was unset, so the two characters disappeared. The array would be similarly interpolated if it was a built-in or named with 'word' characters. Once this is done, the string goes through compilation as a regex, which applies magic to the metacharacters: qw< \ ^ . $ | ( ) [ ] * + ? { } >. At this point the question mark and star act as quantifiers on the 'r' and @ respectively, and require escaping to avoid this. > I also encountered the (?-xism:roger\? what the [EMAIL PROTECTED]) using > qr. How do you get this with a plain qr()? I can only achieve it by manually escaping these characters: \Q also escapes the spaces for you. > My first try with quotemeta q() also had some issues: > > #!/usr/bin/perl -w > > use strict; > > my $string; > $string = 'I saw Roger and I said :roger? what the @*$!'; OK, single-quote context, so no escaping and no interpolation. Actually, the sequences \\ and \' are changed to \ and ' (the latter being whatever delimiter is used for the string representation) but no other changes are made. The string is stored 'as-is'. > my $var1 = quotemeta q(roger? what the @*$!); $var1 eq 'roger\?\ what\ the\ [EMAIL PROTECTED]' > my $var2 = quotemeta q(Hi roger...nice to meet you); $var2 eq 'Hi\ roger\.\.\.nice\ to\ meet\ you' > > $string =~ s/$var1/$var2/e; FIrstly the pattern string undergoes double-quote interpolation and because of the /e, the replacement expression $var2 gets executed instead of interpolated. In the case of a simple string value this amounts to the same thing. So the match string is roger\?\ what\ the\ [EMAIL PROTECTED] which correctly has all regex metacharacters escaped, while the replacement string is Hi\ roger\.\.\.nice\ to\ meet\ you > print $var1 ."\n"; > print $string . "\n"; > > E:\d_drive\perlStuff\guests>sub_roger.pl > roger\?\ what\ the\ [EMAIL PROTECTED] > I saw Roger and I said :Hi\ roger\.\.\.nice\ to\ meet\ you So the pattern string is correct and the match succeeds, but the replacement string has been modified by quotemeta as well, and is reproduced as such. > It does succeed in the substitution, though, the first trial using > all the characters that did so. So one more change, a backtrack: > my $var2 = 'Hi roger...nice to meet you'; > and ... Voila!: > E:\d_drive\perlStuff\guests>sub_roger.pl > roger\?\ what\ the\ [EMAIL PROTECTED] > I saw Roger and I said :Hi roger...nice to meet you Yes, exactly. You need to escape the metacharacters in the pattern string but, since the regex metacharacters are irrelevant to the replacement string you should simply make sure that your variable contains exactly the characters you want. In my reply, I was using $var1 = quotemeta q{roger? what the @*$!}; as a replacement for Scott's $var1 = qr{roger? what the @*$!}; What both quotemeta and \Q do, by the way, is simply to escape all \W (non-word) characters in the string. This covers regex metacharacters, whitespace (when used in conjunction with the /x modifier) and variable prefixes ($, @, %). Remember, though, that the \Q escaping is done /after/ all other interpolation in the string, which is why $var1 = quotemeta q{roger? what the @*$!}; is different from $var1 = qq{\Qroger? what the @*$!}; I hope this helps, and is clear: it's a bit of a minefield. Alert readers please check for any mistakes! Thanks, Rob -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]