0

Using preg_replace, I would like to replace all instances of a "pipe not followed by http://", If the pipe is followed by http://, then do nothing. For example,

The following string:

http://www.xyz.org/docs/pdfs/2014/file_name_1.pdf|file_name_2.pdf|http://www.xyz.org/docs/pdfs/2014/file_name_3.pdf|

Once run thru preg_replace will become:

http://www.xyz.org/docs/pdfs/2014/file_name_1.pdf|http://www.xyz.org/docs/pdfs/2014/file_name_2.pdf|http://www.xyz.org/docs/pdfs/2014/file_name_3.pdf|

The code I have in place so far replaces all pipes.

$string = trim(preg_replace("/\|\|+/", "|", $string));
$string = str_replace("|", "|http://www.xyz.org/docs/pdfs/2014/", $string);
1

2 Answers 2

2

I think you simply need to use a 'negative lookahead'...

CODE:

<?php
   $a = 'http://www.xyz.org/docs/pdfs/2014/file_name_1.pdf|file_name_2.pdf|http://www.xyz.org/docs/pdfs/2014/file_name_3.pdf|';
   $b = preg_replace("/\|(?!http:\/\/)/",'|http://www.xyz.org/docs/pdfs/2014/',$a);
   echo 'A: '.$a."\n";
   echo 'B: '.$b."\n";
?>

This regular expression \|(?!http:\/\/) will match...

  • \| a vertical bar
  • (?!http:\/\/) not followed by http:// (this is the negative lookahead zero width assertion)

OUTPUT:

> A: http://www.xyz.org/docs/pdfs/2014/file_name_1.pdf|file_name_2.pdf|http://www.xyz.org/docs/pdfs/2014/file_name_3.pdf|
> B: http://www.xyz.org/docs/pdfs/2014/file_name_1.pdf|http://www.xyz.org/docs/pdfs/2014/file_name_2.pdf|http://www.xyz.org/docs/pdfs/2014/file_name_3.pdf|http://www.xyz.org/docs/pdfs/2014/

This is a simplified example which also replaces the last trailing '|' in your string, but you get the idea of the regex.
If needed you could handle the trailing bar with this variation of the regex /\|(?!(http:\/\/|$))/ which uses the lookahead to check for end of string too.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks. Your example removes file_name_2.pdf from the string altogether, where as I need 'xyz.org/docs/pdfs/2014' inserted before the file name.
I realised that and was correcting my reply as you posted :-)
Thanks. I tested yours and it works properly. The remaining issue is that it converts the last pipe with the URL, would prefer the last pipe be stripped from the string. I have tried to make that work but I keep messing up the other aspects.
Doesn't the alternative regex given in the last sentence handle the trailing pipe? /\|(?!(http:\/\/|$))/ I think it should leave the pipe unreplaced as per the desired result you gave in the question.
0

Maybe by using explode and test one by one

$string = 'http://www.xyz.org/docs/pdfs/2014/file_name_1.pdf|file_name_2.pdf|http://www.xyz.org/docs/pdfs/2014/file_name_3.pdf|';
$string = addHttp($string); 

function addHttp($string) {
    $a_string = explode('|', $string);
    $return_string = '';
    foreach($a_string as $a_s) {
        if(trim($a_s) == '')
            continue; 

        if(preg_match('#^http://#', $a_s))
            $return_string .= $a_s.'|';
        else
            $return_string .= 'http://'.$a_s.'|';
    }

    return $return_string;
}

EDIT : I changed strpos by preg_match

2 Comments

I did not think of using an explode. Thank you, that works and I am progressing nicely.
This works, but you're doing a lot of unnecessary work. preg_replace() is perfect for this job, as Gavin's answer demonstrates.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.