Emanuel has asked for the wisdom of the Perl Monks concerning the following question:

Hello

I'm feeling pretty ashamed to ask this, but i've been trying for pretty long now to no avail, and also searching perlmonks and google didn't point me to any hints. So I'm asking it here.

I have the following code, which should do nothing less than to transform pseudo-html line into real html. The problem where everything fails is in the final translation. The regex isn't "working" as expected. I guess it has something to do with $complete containing characters, that represent special chars to a regex (like / . [] etc).

any help on this would be greatly appreciated

#!/usr/bin/perl -w use strict; my $source = <<EOF; [link title:Google]http://www.google.com[/link] [link title:Altavista]http://www.altavista.com[/link] [link title:perlmonks]http://www.perlmonks.com[/link] [link title:and now something completely different]http://www.perlmonk +s.com/index.pl?node_id=104944[/link] EOF my ($complete,$title,$url); while ($source =~ /(\[link title:(.*?)\](.*?)\[\/link])/gi) { $complete = $1; $title = $2; $url = $3; print "complete: $1\ntitle: $title\nurl: $url\n"; $source =~ s/$complete/<a href='$url'>$title<\/a>/g || print " +regex failed\n"; } print $source."\n";


Emanuel

Replies are listed 'Best First'.
Re: replacing variable in regex - probs with special chars?
by dragonchild (Archbishop) on Jan 30, 2003 at 18:24 UTC
    To solve your problem, use \Q and \E. (Read the Camel book to learn what they do.)

    Personally, I'd use a templating system like HTML::Template or Mason vs. rolling your own. *shrugs* I don't like re-inventing wheels that do more than I'll ever make them do.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      unfortunatly the whole thing isn't used for webpages or any of the like. HTML::Template and Mason are not suited for the whole purpose of what this is doing (it's just an excerpt out of the whole thing).

      I'm going to dig out my copy of the camel book and start reading, thanks for the direction!

      Emanuel

        Yes, you want:

        s/\Q$complete\E/...
        because $complete has metacharacters in it. Pretty much any time you want to stick a variable in a regex, you want to use \Q...\E. The only exception is if the variable is supposed to contain a regex itself, but that can get dangerous (arbitrary perl code in regexes, etc).

        Also, maybe Template::Toolkit would be of use. It just does general text templates, making no assumptions about web apps or HTML.

Re: replacing variable in regex - probs with special chars?
by fletcher_the_dog (Friar) on Jan 30, 2003 at 20:13 UTC
    Try changes your substitution to
    $source =~ s/\Q$complete\E/<a href='$url'>$title<\/a>/g || print "
    The "\Q" puts backslashes in front of all the special characters in '$complete'. This will make the regex treat them literally instead of a as metacharacters.
Re: replacing variable in regex - probs with special chars?
by integral (Hermit) on Jan 31, 2003 at 07:43 UTC
    Surely the code can be simplified by using a s///g at the top level instead of looping?
    $source =~ s/(\[link title:(.*?)\](.*?)\[\/link])/<a href='$3'>$2<\/a> +/gi;
    The obvious limitation over the original solution is that it doesn't allow one to loop, but perhaps this would work?
    while ($source =~ s/\G(\[link title:(.*?)\](.*?)\[\/link])/<a href='$3 +'>$2<\/a>/i) { print "complete: $1\ntitle: $2\nurl: $3\n"; }

    --
    integral, resident of freenode's #perl
    
Re: replacing variable in regex - probs with special chars?
by clairudjinn (Beadle) on Jan 31, 2003 at 08:04 UTC
    while ($source =~ /(\[link title:(.*?)\](.*?)\[\/link])/gi)
    I think you probably meant to backslash the last ']' character also.
      yep, sure did... evil typo
      E.