Reputation: 2050
I have a variable that contains some links. Now I want to strip the <a>
tags from the link which has been clicked to inform the end user of the current page.
Input string and my code:
$links = '<a href="#" onclick="sort_data(\'All\',\'all\')">All</a> | <a href="#" onclick="sort_data(\'Diversified\',\'1\')">Equity</a> | <a href="#" onclick="sort_data(\'Liquid\',\'1\')">Liquid</a> | <a href="#" onclick="sort_data(\'Sector\',\'1\')">Sector</a>';
if (preg_match('/<A HREF="#" onclick="(.*?)>Equity/', $links))
{
echo preg_replace('/<A HREF=(.*?)>Equity/', 'Equity', $links);
}
This is replacing everything written before Equity
while I want that only Equity
's anchor tag should be removed and the inner text should remain as it is.
What am I doing wrong here? Is there some better way to do this?
Upvotes: 0
Views: 195
Reputation: 47874
Assuming your string is part of a larger HTML string, you can use a legitimate DOM parser to isolate and replace the hyperlink with the corresponding text.
CODE: (Demo)
$links = <<<HTML
<div>
<a href="#" onclick="sort_data('All','all')">All</a> | <a href="#" onclick="sort_data('Diversified','1')">Equity</a> | <a href="#" onclick="sort_data('Liquid','1')">Liquid</a> | <a href="#" onclick="sort_data('Sector','1')">Sector</a>
</div>
HTML;
$target = 'Equity';
$doc = new DOMDocument();
$doc->loadHTML($links, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new DOMXPath($doc);
$a = $xpath->query("//a[text()='$target']")->item(0);
$a->parentNode->replaceChild($doc->createTextNode($target), $a);
echo $doc->saveHTML();
Raw output:
<div>
<a href="#" onclick="sort_data('All','all')">All</a> | Equity | <a href="#" onclick="sort_data('Liquid','1')">Liquid</a> | <a href="#" onclick="sort_data('Sector','1')">Sector</a>
</div>
Rendered output:
Upvotes: 0
Reputation: 7383
You have multiple flaws in your code:
i
(case insensitive) option or change the reg exp.</a>
.*
will consume every link in front of the searched one.Try this:
$links='<a href="#" onclick="sort_data('All','all')">All</a> | <a href="#" onclick="sort_data('Diversified','1')">Equity</a> | <a href="#" onclick="sort_data('Liquid','1')">Liquid</a> | <a href="#" onclick="sort_data('Sector','1')">Sector</a>';
if(preg_match('/<A([^<>]*)>Equity</A>/i',$links)) {
echo preg_replace('/<A([^<>]*)>Equity</A>/i','Equity',$links);
}
Upvotes: 0
Reputation: 21565
If all you want to do is get rid of the <A HREF=...>
and </A>
tags, why not use the strip_tags function?
Upvotes: 0
Reputation: 27313
you should use the case insensitive flag on preg_match and preg_replace. Also preg_match would match only one link, if you need to replace all link preg_match_all would be better.
$links='<a href="#" onclick="sort_data(\'All\',\'all\')">All</a> | <a href="#" onclick="sort_data(\'Diversified\',\'1\')">Equity</a> | <a href="#" onclick="sort_data(\'Liquid\',\'1\')">Liquid</a> | <a href="#" onclick="sort_data(\'Sector\',\'1\')">Sector</a>
';
if(preg_match('/<A HREF="#" onclick="(.*?)>Equity/i',$links))
{
echo preg_replace('/<A HREF=([^>]*)>Equity/i','<A $1>Equity',$links);
}
Note: I don't know why you are doing that on server side but might be better to do it on client side with a javascript framework, jquery would be perfect to do such manipulations. Also you have better to make non intrusive javascript that really better for maintenance,
Upvotes: 1
Reputation: 27478
Replace is by default "greedy" and is matching the first "<A HREF..." all the way through to your last "Equity".
Try /<A HREF=([^<>]*?)>Equity/
The [^<>]
should restrict your selection to character that are NOT angle brackets and so restrict it to a single href tag.
Upvotes: 3