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

I have the following regex:
$string =~ s!http://(.+?)(\s|$)![<a href="http://">Link</a>] !;

This produces the following::
[<a href="[<a href="[<a href="[<a href="[<a href="[<a href="[<a href=" +[<a href="http://">Link</a>]

It has to do with the double slashes. If i change it to:
$string =~ s!http://(.+?)(\s|$)![<a href="http:a//">Link</a>] !;

it produces:
[<a href="http:a//">Link</a>]

Any variation where the "//" is not right after the ":" works like you would expect, but putting it right next to the ":" always produces repetative garbage. Even just a single slash after the ":" works.

Ideas on why it might be doing that? I can't explain it.

perl version 5.8.0

I just tried it on a machine with perl 5.8.1-RC3 and it works fine. Is this a bug in Perl 5.8.0? If so, how does one work around it? I can't upgrade the perl install on that machine.

Replies are listed 'Best First'.
Re: Double slashes in regex causing problems
by dave_the_m (Monsignor) on May 14, 2004 at 14:08 UTC
    I tried it on 5.8.0 and couldn't reproduce what you're seeing. Could you (a) include a complete standalone script that reproduces the problem, and (b) show the output of perl -V

    Thanks, Dave.

      This is really strange.

      The code was modifying a value in a hash.
      $$mhash{entries}{$msg}{text} =~ s!http://(.+?)(\s|$)!"\[<a href=\"http +://$1\">Link</a>\]"!ge;

      I change the above to:
      my $string = $$mhash{entries}{$msg}{text}; $string =~ s!http://(.+?)(\s|$)!"\[<a href=\"http://$1\">Link</a>\]"!g +e;

      And it works fine.
        Your initial question didn't mention /g or /e, but your actual example uses both. I'm not sure why you want the /e option here at all.

        However, I've confirmed that (on my 5.6.0 ActiveState build) the deep hash value is not being modified when bound as the lvalue against a s/// operator containing slashes, but it works with a trivial pattern and replacement.

        Update: Duh, a typo. This is working fine for me.

        use strict; use warnings; use Data::Dumper; my $msg = 'a'; my $mhash; $$mhash{entries}{$msg}{text} = "This is a http://foo/bar.html test."; $$mhash{entries}{$msg}{text} =~ s!http://(\S+)![<a href="http://$1" >f +oo</a>]!g; print Dumper $mhash; __OUTPUT__ $VAR1 = { 'entries' => { 'a' => { 'text' => 'This is a [<a href="http://foo/ +bar.html" >foo</a>] test.' } } };
        This sort of pattern is common in blogs and stuff, to find and linkify things that look like URLs. However, you need to be careful about trailing characters that the user has typed as a part of their blog entry. For example, see here (http://perlmonks.org) for a DNS error or here (http://perlmonks.org/index.pl) for a 404 error because of the closing parenthesis characters.

        --
        [ e d @ h a l l e y . c c ]

        In your orignal posting you didn't have the /e on the end of the regex. Do you really want this? And like I said, Could you (a) include a complete standalone script that reproduces the problem, and (b) show the output of perl -V. The script only needs to be 3 lines lines long; just enough to turn the snippets you show above into something I can reproduce here. Dave.