Reputation: 5023
Sorry about the title I honestly dont know how to explain it properly.
I am making a small shortcode function that needs to replace shortcodes with html output.
The preg_match_all finds everything I need but the preg_replace is replacing the same match over and over again. Here is the demo https://eval.in/139727
I am sure I made a mess in those foreach loops but just cant figure it out.
$text = 'Some text and some [link link="linkhref1" text="Text1"],[link link="linkhref2" text="Text2"]';
function shortcodes($text) {
$shortcodes = array(
'link' => array(
"check" => "[link",
"type" => "link",
"match" => "#\[link(.*?)link\=\"(.*?)\"(.*?)text\=\"(.*?)\"#Ui",
"replace" => "/\[link(.*?)\]/s"
)
);
foreach ($shortcodes as $index => $shortcode) {
if (strpos($text, $shortcode['check']) !== false) {
$text = shortcode_replace($shortcode, $text);
}
}
return $text;
}
function shortcode_replace($shortcode, $text) {
$replacement = '';
preg_match_all($shortcode['match'], $text, $matches);
switch ($shortcode['type']) {
case "link":
foreach ($matches[4] as $index => $match) {
$link = $matches[2][$index];
$linktext = $matches[4][$index];
$replacement .= '<a href="' . $link . '">' . $linktext . '</a>';
$text = preg_replace($shortcode['replace'], $replacement, $text);
}
}
return $text;
}
echo shortcodes($text);
any help is appreciated!
Upvotes: 0
Views: 139
Reputation: 1534
Here is a working version :
<?php
$text = 'Some text and some [link link="linkhref1" text="Text1"],[link link="linkhref2" text="Text2"]';
function shortcodes($text) {
$shortcodes = array(
'link' => array(
"check" => "[link",
"type" => "link",
"match" => "#\[link(.*?)link\=\"(.*?)\"(.*?)text\=\"(.*?)\"#",
"replace" => "/\[link(.*?)\]/s"
)
);
foreach ($shortcodes as $index => $shortcode) {
if (strpos($text, $shortcode['check']) !== false) {
$text = shortcode_replace($shortcode, $text);
}
}
return $text;
}
function shortcode_replace($shortcode, $text) {
$replace = '';
preg_match_all($shortcode['match'], $text, $matches);
switch ($shortcode['type']) {
case "link":
foreach ($matches[4] as $index => $match) {
$link = $matches[2][$index];
$linktext = $matches[4][$index];
$replace .= '<a href="' . $link . '">' . $linktext . '</a>';
$whatToReplace = '[link link="'.$link.'" text="'.$linktext.'"]';
$text = str_replace($whatToReplace, $replace, $text);
}
}
return $text;
}
echo shortcodes($text);
I'm not very good at RegExp, i modified the "match" to match all the links ( with what you got, it didn't )
You need to identify the exact [link ] to replace, and not all all of them. In my opinion, this is the correct way to identify the link, You can also identify it using strpos() ( getting the start and end of the string) or see where the [link starts and the first ] is .
A better option can be to create a regexp with the unique values for it , which can compensate for extra spaces between tags
Hopefully this is of help to you
Upvotes: 0
Reputation: 8072
There was a problem in regex i've changed it. Also you don't need preg_replace there.
<?php
$text = 'Some text and some [link link="linkhref1" text="Text1"],[link link="linkhref2" text="Text2"]';
function shortcodes($text) {
$shortcodes = array(
'link' => array(
"check" => "[link",
"type" => "link",
"match" => "#\[link(\s+)link\=\"([^\"]+)\"(\s+)text\=\"([^\"]+)\"\]#Ui",
"replace" => "/\[link(.*?)\]/s"
)
);
foreach ($shortcodes as $index => $shortcode) {
if (strpos($text, $shortcode['check']) !== false) {
$text = shortcode_replace($shortcode, $text);
}
}
return $text;
}
function shortcode_replace($shortcode, $text) {
$replace = '';
preg_match_all($shortcode['match'], $text, $matches);
switch ($shortcode['type']) {
case "link":
var_dump($matches);
foreach ($matches[4] as $index => $match) {
$link = $matches[2][$index];
$linktext = $matches[4][$index];
$replace = '<a href="' . $link . '">' . $linktext . '</a>';
$text = str_replace($matches[0][$index], $replace, $text);
}
}
return $text;
}
echo shortcodes($text);
Upvotes: 1