<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
    <title></title>
  </head>
  <body bgcolor="#ffffff" text="#000000">
    On 25/10/2010 07:58, Peter Hallam wrote:<br>
    <blockquote cite="mid:20101024235859.GD28070@Red.inatick.com"
      type="cite">
      <blockquote type="cite">
        <pre wrap="">my $url = '<a class="moz-txt-link-freetext" href="http://www.FOo.COm/wibbLE">http://www.FOo.COm/wibbLE</a>';
my $search = '^([^:]+://[^/]+)/?(.*)?$';
my $replace = '\L$1\E/$2';
print $url if $url =~ /$search/$replace/;
</pre>
      </blockquote>
      <pre wrap="">
Given $url and $search I came up with:
  print $url if $url =~ s|$search|lc($1)."/$2"|e;

However, I'd be tempted to capture the forward slash to with:
  my $search = '^([^:]+://[^/]+)(/?.*)?$';

Which then alleviates the need to use the pipe character in the substitution:

  print $url if $url =~ s/$search/lc($1).$2/e;
</pre>
    </blockquote>
    Thanks Peter,<br>
    <br>
    I was also trying to see if I could guarantee that the URL would end
    up with a trailing slash after the hostname, as well as not having
    (possibly untrusted) replacement text as an expression in the RHS.<br>
    <br>
    I suspect using any escape sequence (either \L or back references
    $1...n) in the RHS (replacement) part of a substitution (s///) is
    going to only work if it is a literal, not inside a variable.
    Passing just '$1' inside a variable without "/e" (eval) isn't going
    to expand, and as soon as you have "/e" or eval, then your
    replacement string could be armed with Bad Stuff (like $replace =
    'unlink "/some/file"').<br>
    <br>
    My next test case I hit was:<br>
    <font color="#000099"><tt>my $search = '^(<a class="moz-txt-link-freetext" href="http://">http://</a>[^/:]+):80(/.*)$';<br>
        my $replace = '$1$2';<br>
      </tt><tt>$url =~ s!$search!$replace!;</tt></font><font
      color="#000099"><tt><br>
      </tt></font>
    <br>
    In order to strip out default port , but again, I end up with $url =
    '$1$2', not the sanitised string.<br>
    <br>
    <br>
    So I think that, if I fetch my replace string from the database, and
    a add a pair of double quotes within the string, and use /ee (yep,
    double e), then I think it works:<br>
    <tt><font color="#000099">my $search =
        '^([^:]+://[^/]+(:\d+)?)/?(.*)?$'; # From database<br>
        my $replace = '\L$1\E/$3'; # From database<br>
        my $url = '<a class="moz-txt-link-freetext" href="http://www.FOo.COm:80/wibbLE">http://www.FOo.COm:80/wibbLE</a>';<br>
        $replace = '"' . $replace . '"';<br>
        print $url . "\n" if $url =~ s/$search/$replace/ee; # Gives:
        <a class="moz-txt-link-freetext" href="http://www.foo.com:80/wibbLE">http://www.foo.com:80/wibbLE</a><br>
        <br>
      </font></tt>Of course, then using:<br>
    <font color="#000099"><tt>my $search =
        '^([^:]+://[^/]+(:\d+)?)/?(.*)?$'; # From database<br>
        my $replace = '" eq ""; print time(); print "';<br>
        my $url = '<a class="moz-txt-link-freetext" href="http://www.FOo.COm:80/wibbLE">http://www.FOo.COm:80/wibbLE</a>';<br>
        $replace = '"' . $replace . '"';<br>
        print $url . "\n" if $url =~ s/$search/$replace/ee;</tt></font><br>
    <br>
    Just gives me the time (safest thing I could think of), and
    potentially a lot of trouble. So lastly:<br>
    <font color="#000099"><tt>my $search =
        '^([^:]+://[^/]+(:\d+)?)/?(.*)?$'; # From database<br>
        my $replace = '\L$1\E/$3'; # From database<br>
        $replace =~ s/"/\\"/g; # Protection from embedded code<br>
        $replace = '"' . $replace . '"'; # Put in a string for /ee<br>
        my @urls = qw ( <a class="moz-txt-link-freetext" href="http://www.FOo.COm:80/wibbLE">http://www.FOo.COm:80/wibbLE</a> <a class="moz-txt-link-freetext" href="http://www.FOo.COm/">http://www.FOo.COm/</a>
        <a class="moz-txt-link-freetext" href="http://www.FOo.COm">http://www.FOo.COm</a> );<br>
        foreach (@urls) {<br>
        &nbsp; print "$_\n" if s/$search/$replace/ee;<br>
        }</tt></font><br>
    <br>
    <br>
    Hmm. Ponderous. :)<br>
    <br>
    &nbsp; James<br>
    <div class="moz-signature">-- <br>
      <strong>James Bromberger</strong><br>
      Aus Mobile: +61 422 166 708<br>
      Email: james <i>_AT_</i> rcpt.to, Web: <a
        href="http://www.james.rcpt.to/">www.james.rcpt.to</a><br>
      MSN: james<i>_AT_</i>rcpt.to, AIM: JamesEBromberger, Skype:
      james.bromberger
      <small>(<i>_AT_</i> -&gt; @)</small></div>
  </body>
</html>