0

I have a string of comma separated values that comes from a database, which actually are image paths. Like so:

/images/us/US01021422717777-m.jpg,/images/us/US01021422717780-m.jpg,/images/us/US01021422717782-m.jpg,/images/us/US01021422718486-m.jpg

I then do like below, to split them at the , and convert them into paths for the web page.

preg_replace('~\s?([^\s,]+)\s?(?:,|$)~','<img class="gallery" src="$1">', $a)

Works well, but in one place further in my page, I need to change the -m to -l (which means large)

When I do like below (put a str_replace inside the preg_replace), nothing happens. How can I do something like this?

preg_replace('~\s?([^\s,]+)\s?(?:,|$)~','<img class="gallery" src="$1" data-slide="'.str_replace('-m','-l','$1').'">', $a)

1
  • Please inform volunteers if their answer are incorrect. If one or more of the answers is correct, please award the green tick to the answer that you feel is "best" / "most helpful" / etc. 30% of all php question are currently deemed "unanswered" on Stackoverflow because they don't have a green tick. Commented Feb 13, 2018 at 12:25

5 Answers 5

1

You're putting the str_replace() call in the output pattern for the preg_replace() call. That means preg_replace() is treating it as literal text.

What you want is something like this:

$imgtag = preg_replace(match, replacement, $a);
$imgtag = str_replace('-m','-l',$imgtag);

But, in my opinion it would be safer and easier to debug this stuff if you changed the order of your replacement operations, something like this:

foreach ($path in explode(",", $a)) {
  $path = str_replace('-m','-l',$path);
  $imgtag= sprintf ('<img class="gallery" src="%s">', $path);
  /* do something with the $imgtag */
}

That way you don't have to whistle into your modem :-) to program that regexp.

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

Comments

0

Use str_replace on preg_replace return

$large = str_replace('-m','-l', preg_replace('~\s?([^\s,]+)\s?(?:,|$)~','<img class="gallery" src="$1">', $a));

Output will be

<img class="gallery" src="/images/us/US01021422717777-l.jpg">
<img class="gallery" src="/images/us/US01021422717780-l.jpg">
<img class="gallery" src="/images/us/US01021422717782-l.jpg">
<img class="gallery" src="/images/us/US01021422718486-l.jpg">

1 Comment

The data-slide needs to go with it. Like in my question.
0

Use preg_replace_callback():

preg_replace_callback(
    '~\s?([^\s,]+)\s?(?:,|$)~',
    function (array $matches) {
        $src   = $matches[1];               // this is "$1"
        $slide = str_replace('-m', '-l', $matches[1]);
        return '<img class="gallery" src="'.$src.'" data-slide="'.$slide.'">';
    },
    $a
);

Instead of the replace expression, preg_replace_callback() gets as its second argument a function that receives the list of matched expressions and returns the replacement string.

Comments

0

Actually your str_replace is simply invoked before preg_replace is invoked. Result of str_replace is then passed as argument to preg_replace.

What I could suggest is using preg_replace_callback:

function replace_img($match)
{
  return '<img class="gallery" src="' .
    $match[1] .
    '" data-slide="' .
    str_replace('-m','-l',$match[1]) .
    '">';
}

preg_replace_callback('~\s?([^\s,]+)\s?(?:,|$)~','replace_img', $a);

Comments

0

If you need two separate outputs from each comma-separated value, I would write a pattern that stores the fullstring match and the substrings on either side of the m in each file.

*note: I match the trailing - in the first capture group and the leading . in the second capture group for minimal assurance of accuracy. This is somewhat weak validation; you can firm it up if your project requires it by adding literal or more restrictive pattern components in the capture groups.

Code: (Demo)

$csv='/images/us/US01021422717777-m.jpg,/images/us/US01021422717780-m.jpg,/images/us/US01021422717782-m.jpg,/images/us/US01021422718486-m.jpg';
if(preg_match_all('~([^,]+-)m(\.[^,]+)~',$csv,$out,PREG_SET_ORDER)){
    foreach($out as $m){
        $mediums[]="<img class=\"gallery\" src=\"{$m[0]}\">";
        $larges[]="<img class=\"gallery\" src=\"{$m[0]}\" data-slide=\"{$m[1]}l{$m[2]}\">";
    }
}

var_export($mediums);
echo "\n\n";
var_export($larges);

Output:

array (
  0 => '<img class="gallery" src="/images/us/US01021422717777-m.jpg">',
  1 => '<img class="gallery" src="/images/us/US01021422717780-m.jpg">',
  2 => '<img class="gallery" src="/images/us/US01021422717782-m.jpg">',
  3 => '<img class="gallery" src="/images/us/US01021422718486-m.jpg">',
)

array (
  0 => '<img class="gallery" src="/images/us/US01021422717777-m.jpg" data-slide="/images/us/US01021422717777-l.jpg">',
  1 => '<img class="gallery" src="/images/us/US01021422717780-m.jpg" data-slide="/images/us/US01021422717780-l.jpg">',
  2 => '<img class="gallery" src="/images/us/US01021422717782-m.jpg" data-slide="/images/us/US01021422717782-l.jpg">',
  3 => '<img class="gallery" src="/images/us/US01021422718486-m.jpg" data-slide="/images/us/US01021422718486-l.jpg">',
)

Comments

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.