developer
developer

Reputation: 2050

Change HTML hyperlink to plain text if contains specified text

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

Answers (5)

mickmackusa
mickmackusa

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

Christian Strempfer
Christian Strempfer

Reputation: 7383

You have multiple flaws in your code:

  1. Your searching for upper case letters, although you used lower case letters. To fix this use the i (case insensitive) option or change the reg exp.
  2. You forgot the closing tag </a>.
  3. The greedy * will consume every link in front of the searched one.
  4. (The if branch is possibly unnecessary, if you ony want to continue to use the manipulated string.)

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

MiffTheFox
MiffTheFox

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

RageZ
RageZ

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

James Anderson
James Anderson

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

Related Questions