Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

regex not working with double quote. very baffled!

Status
Not open for further replies.

Zim88

Programmer
Jan 29, 2008
2
0
0
US
So I'm trying to do a number of regex across a file, which seems straight forward enough.

However, when I try to regex a string with characters \ and " my regex fails to find the string.

E.g. the following can be found
START

But the following cannot
\"START\"

Here's the pertinent code

$findstart = "\\\"START\\\"";
$replacestart = "replace string";
$infile =~ s/$findstart/$findstart\n$replacestart/g;

I've tried
$findstart = '\"START\"';

However, when I enter it in like:
$infile =~ s/\"START\"/$findstart\n$replacestart/g;

Then it works. Does anyone know what I'm doing wrong?

Thanks!!!
 
use strict;
use warnings;

my $test1 = "START";
my $test2 = "\"START\"";

print $test1 . "\n" . $test2 . "\n\n";

if ($test1 =~ m/\"START\"/)
{
print "Found \"START\" in test1.\n";
}
if ($test2 =~ m/\"START\"/)
{
print "Found \"START\" in test2.\n";
}

[red]"... isn't sanity really just a one trick pony anyway?! I mean, all you get is one trick, rational thinking, but when you are good and crazy, oooh, oooh, oooh, the sky is the limit!" - The Tick[/red]
 
the double-quotes should be no problem but the backslash is a meta character, all you really need to do is use the \Q (quotemeta) option with your regexps search pattern:

Code:
$infile =~ s/\Q$findstart\E/$findstart\n$replacestart/g;

that escapes all non-word characters in the search pattern except $ and @. So any \ in the pattern will be treated literally instead of being interpolated as a meta character. Using the \E is really optional in this case as you are escaping the entire search string. \E just tells perl where to end \Q. Using \Q on search patterns is a powerful and useful tool, remember to put it in your perl toolbox and use it when needed.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Try: -

Code:
$findStart = qr/\"START\"/;
$replaceStart = "replace string";
$inFile =~ s/(?<=$findStart)/\n$replaceStart/g;

qr// tells perl that you want to use the string in a regexp.

The (?<=$findStart) is a zero-width look behind. It essentially finds "START" and then inserts \n$replaceStart afterwards.
 
The zero-width positive look behind assertion will not work as stated above because you didn't escape the backslashes in the cashed regex. You could either escape them, use qr'' instead, or just use the method that Kevin demonstrated using \Q \E and string literals. The latter is the method I would vote for.

Code:
[url=http://perldoc.perl.org/functions/use.html][black][b]use[/b][/black][/url] [green]strict[/green][red];[/red]
[black][b]use[/b][/black] [green]warnings[/green][red];[/red]

[url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]$data[/blue] = [url=http://perldoc.perl.org/functions/do.html][black][b]do[/b][/black][/url] [red]{[/red][url=http://perldoc.perl.org/functions/local.html][black][b]local[/b][/black][/url] [blue]$/[/blue][red];[/red] <DATA>[red]}[/red][red];[/red]

[black][b]my[/b][/black] [blue]$find[/blue] = [red]q{[/red][purple]\"START\"[/purple][red]}[/red][red];[/red]
[black][b]my[/b][/black] [blue]$append[/blue] = [red]q{[/red][purple]replace string[/purple][red]}[/red][red];[/red]

[blue]$data[/blue] =~ [red]s{[/red][purple](?<=[purple][b]\Q[/b][/purple][blue]$find[/blue][purple][b]\E[/b][/purple])[/purple][red]}[/red][red]{[/red][purple][purple][b]\n[/b][/purple][blue]$append[/blue][/purple][red]}[/red][red];[/red]

[url=http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/url] [blue]$data[/blue][red];[/red]

[teal]__DATA__[/teal]
[teal]But the following cannot[/teal]
[teal]\"START\"[/teal]

[teal]Here's the pertinent code[/teal]
[tt]------------------------------------------------------------
Pragmas (perl 5.10.0) used :
[ul]
[li]strict - Perl pragma to restrict unsafe constructs[/li]
[li]warnings - Perl pragma to control optional warnings[/li]
[/ul]
[/tt]- Miller
 
I beg to differ. I tested this before posting and it worked on my system. The whole script was: -

Code:
undef $/;
$inFile = do{ local $/; <DATA> };

print "BEFORE: $inFile\n";

$findStart = qr/\"START\"/;
$replaceStart = "replace string";
$inFile =~ s/(?<=$findStart)/\n$replaceStart/g;

print "AFTER : $inFile\n";

__DATA__
"START" and then some more text

I'd be interested to see if it works on other systems.

Warren

 
Warren,

The string he was trying to match was the literal \"START\" not "START". That is why neither of your code examples is quite correct.

The possible corrections for this are stated in my previous post.

- Miller

 
That's great information. Thanks everyone!!!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top