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

I have a list of things to s/// for from a table and we really have no idea what the user will type in. Sometimes it words, sometimes numbers, sometimes things like :) or *smiles* or <smiles>, etc.

If these things are found it's suppose to s/// it with an image tag. It's not substituting html tags with new HTML, it's performing this to plain text and making an image tag out of it.

In the CB it was mentioned to use Q\$var\E , this stopped the errors I had but it's not s/// everything. In fact it only substitutes real words like "cat" or "dog" but nothing like :) or *text*. On top of that it's not always substituting anything, it picks and chooses when it wants to work and what will get substituted.

I think ther is an error in the section where they say what they want to s/// but maybe it's my logic on how to do this.

Can someone see from the example what might be causing these issues?

my $data = qq(SELECT id, name, location, face FROM emoticons); my $sth = $dbh->prepare($data); $sth->execute() or die $dbh->errstr; my ($id, $name, $location, $face); $sth->bind_columns(\$id, \$name, \$location, \$face); foreach my $line (reverse @keep) { my ($username, $message, $date, $ip) = split(/<!!>/, $line); while ($sth->fetch) { $message =~ s|\b\Q$face\E\b| <img src="$location" alt="$name"> | +gi; } if ($message =~ m|^/me|i) { $message =~ s|^/me||i; print qq(<b><i><a href="#" TITLE="Message sent on $date by $ip"> +$username</a></i></b> <i>$message</i><br>); } else { print qq(<b><a href="#" TITLE="Message sent on $date by $ip">$us +ername</a>:</b> $message<br>); } }

Replies are listed 'Best First'.
Re: working with \Q and \E
by Fletch (Bishop) on Feb 24, 2005 at 20:00 UTC

    Probably it's the \b that's screwing you up. Read perldoc perlre for the full explanation, but basically it means a point in the string where there's a transition from a \w character to a \W character (or vice versa). This condition doesn't exist for ":)" so the regex doesn't match and your substitution won't be done.

    DB<4> $_ = ":) cat :)" DB<5> s/\b/^/g DB<6> x $_ 0 ':) ^cat^ :)'
      The solution is to roll your own lookahead and lookbehind. Since the apparent intent is to avoid substituting in the middle of words,
      $message =~ s|(?<!\w)\Q$face\E(?!\w)| <img src="$location" alt="$name" +> |gi
      should work.

      Caution: Contents may have been coded under pressure.
Re: working with \Q and \E
by RazorbladeBidet (Friar) on Feb 24, 2005 at 20:00 UTC
    if you want to substitute actual text (not regexp) - perhaps index would be a better function to use.
    --------------
    It's sad that a family can be torn apart by such a such a simple thing as a pack of wild dogs
Re: working with \Q and \E
by holli (Abbot) on Feb 24, 2005 at 19:59 UTC
    use the quotemeta-function on your input to escape the special characters that affect the regex.

    sillyness, striked. thanks, dave_the_m.


    holli, /regexed monk/
      use the quotemeta-function
      but that's what he's doing: \Q and \E are just shortcuts for calling quotemeta()

      Dave.