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 Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Pattern Matching s/// 2

Status
Not open for further replies.

kennygadams

Programmer
Joined
Jan 2, 2005
Messages
94
Location
US
Hello Programmers,

With s///g, I want to change every occurrence of "flowers" to "Flowers" but I want to avoid making changes to patterns that are found between <>. Can this be done? If so, how?

Here is the code that I'm working with:
Code:
$string = "This red Hibiscus flower was sitting in the warm afternoon sun when it was photographed showing its beauty. <a href=[URL unfurl="true"]http://www.acclaimimages.com/search_terms/flowers.html><font[/URL] color=blue>More flowers Here...</font></a>";

$find = 'flowers';
$replace = 'Flowers';
$string =~ s/$find/$replace/g;

Thanks,


Kenny Adams
 
Would the word flowers, you do not wish to change, always be preceded by a back slash?
If so, test for a match and only replace if no slash.

Keith
 
maybe:

Code:
$string =~ s/(\b[^\/.])$find(\b[^\/.])/$1$replace$2/g;
 
No matter how clever the regex is, there are always cases that break it when trying to parse for text mixed with HTML. To reliably access the information, you should use a module that is designed for parsing.

Use HTML::TokeParser::Simple to break down the string and determine if it is text or not. Do the s///g on text only.

Code:
use HTML::TokeParser::Simple;
$string = "This red Hibiscus flowers was sitting in the warm afternoon sun when it was photographed showing its beauty. <a href=[URL unfurl="true"]http://www.acclaimimages.com/search_terms/flowers.html><font[/URL] color=blue>More flowers Here...</font></a>";
my $parser = HTML::TokeParser::Simple->new( \$string );
my @tokens;
while (my $token = $parser->get_token) {
    if ($token->is_text) {
       my $text = $token->as_is;
       $text =~ s/flowers/Flowers/g;
       push @tokens,$text;
    } else {
        push @tokens, $token->as_is;
    }
}
$new_string = join('',@tokens);
print $new_string;

I know that the code seems overly large to treat such a "small" problem, but in reality, it is the only reliable way to get accurate results.
 
FWIW - I agree wholeheartedly with raklet.
 
Thanks to all for your posts.

audiopro, yes the 'word' would always be preceded by a back slash.

KevinADC, that does the trick.

raklet, that code works great! Thanks!


Kenny Adams
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top