可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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:
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.
回答2:
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">
回答3:
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.
回答4:
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);
回答5:
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">',
)