Jump to content

Replace attributes by tag name


rationalrabbit

Recommended Posts

I have a site that allows members to create pages. These pages consist of small sections some of which HTML can be entered. To keep visitors from straying away from the site, any outside urls are brought up in a modal window. Using inline attributes, a class has to be created (or added to), and the title tag requires some special characters. I can probably get around this by inserting an onclick or something, but there must be a way to replace attributes, and I am at a loss.

The text segments are stored in a database. What I want to do is change the <a> tag attributes as the page is created. So I have a segment of text "$TheText" and I want to change or replace the attribute values.

For instance,

If $TheText contains an 'a' tag that looks like this:

<a class="MyClass" title="Godzilla" href="http://www.godzillaslair.com">Godzilla</a>

I would want to change it to

<a class="MyClass Lightview" title="Godzilla :: {Lightview's parameters}">Godzilla</a>

Or even just replace the attributes entirely, so it would look like

<a class="Lightview" title="{Inserted Title} :: {Lightview's parameters}">Godzilla</a>

In other words, just replacing the attribute values.

 

Of course, I need to see if the attributes exist. I know how to do that and how to get their values. But all that tells me is that I have an 'a' tag in the text with those values for those attributes. I cannot, for example, then do a str_replace in the first example, because there may be another tag in the text with the "MyClass" class.  I can iterate character by character between <a and </a> but there must be a better way.

I'm no good at regex, so I haven't even attempted that.

 

Any suggestions would certainly be appreciated.

Link to comment
Share on other sites

Thanks for the reply MMDE, but I fail to see how preg_replace would solve the problem. Every link is different. There is no pattern to match other than "<a" and ">", and I have to be able to exact match everything in between so that I can save the href, and change, replace, or create the others.

 

I can pull the attribute values and put them into an array and say, "there's no class, so this attribute string needs a class" or "This has a class and I can add a second class to it, or replace it", but I would need to take the full string, change it, and replace the old string with the new string, or replace each selective attribute.  I suppose I could use strpos to know where to put it back. Just seems like the must be an easy way to replace those attributes. Without an ID, Maybe not.

 

I could iterate through a particular 'a' tag, character-by-character till I get to the ">" character, but that's a lot to do at page load. If there was just some way of replacing ... like "this tag does not have a class, so create one" or "This tag has a class, so add to it" or save the href, remove all attributes and put the href back and create a new class and title - all easy to do. It's putting it back into the big string that's got me puzzled. 

Link to comment
Share on other sites

Obtaining the attribute values is no problem.

The problem is knowing where the attribute values came from to put them back.

There may be several links on a page.

Ok, so obtaining the values is no problem, but knowing where to put them in and how to put them in is? Then why are you saying preg_replace can't help you? Searching and then replacing text is what preg_replace does.

Link to comment
Share on other sites

You might have

<a class="MyClass" title="Godzilla" href="http://www.godzillaslair.com">Godzilla</a>

or

<a title="Godzilla" class="MyClass" href="http://www.godzillaslair.com">Godzilla</a>

or

<a href="http://www.godzillaslair.com">Godzilla</a>

also, in the same main string, you may have

<div class="MyClass">

How would you differentiate these with preg_replace?

 

Using PHP's DOM functions, I could grab the attributes and place them in an array, so I would have something like this

$Arr[0][class] = "MyClass";
$Arr[0][title] = "Godzilla";
$Arr[0][href] = "http://www.godzillaslair.com";

$Arr[1][class] = "AnotherClass";
$Arr[1][title] = "";
$Arr[1][href] = "http://www.anotherlink.com";

etc., then alter the values and the first 'a' tag would be the first array, etc., but that would still be pretty clutsy, because I would have to save the old values for replacement comparison.

 

Maybe there's something I don't know about preg_replace (very possible) but I don't know how it would be used. It's not like I can just search for, as an example, "class='MyClass'" and replace it, and it is not like I can search for "<a class="MyClass", etc.

Link to comment
Share on other sites

Or you could use preg_match to get the attributes, and use them:

<?php

$pattern = '~([href|title|class]+)="([a-zA-Z0-9:/.,; ]+)"~';
$string = '<a href="http://phpfreaks.com" title="Coding Freaks" class="myClass">Don\'t click here, it is addicting</a>';
preg_match_all($pattern,$string,$matches);
echo '<pre>' . print_r($matches,true) . '</pre>';

/*output
Array
(
    [0] => Array
        (
            [0] => href="http://phpfreaks.com"
            [1] => title="Coding Freaks"
            [2] => class="myClass"
        )

    [1] => Array
        (
            [0] => href
            [1] => title
            [2] => class
        )

    [2] => Array
        (
            [0] => http://phpfreaks.com
            [1] => Coding Freaks
            [2] => myClass
        )

)
*/

Now you can manipulate them how you wish.

Link to comment
Share on other sites

You might have

<a class="MyClass" title="Godzilla" href="http://www.godzillaslair.com">Godzilla</a>

or

<a title="Godzilla" class="MyClass" href="http://www.godzillaslair.com">Godzilla</a>

or

<a href="http://www.godzillaslair.com">Godzilla</a>

also, in the same main string, you may have

<div class="MyClass">

How would you differentiate these with preg_replace?

You want to differentiate them or just replace them with something else?

They are clearly very different, so differentiate between them would be very easy!

 

But since what you want to replace it with is dynamically changed depending on what it is going to replace, you will need to first extract whatever this replaced text depends on. This could be done with preg_replace and replacing everything else with nothing, then manipulate it as you like and replace it in the original text.

 

Or you could use the DOMdocument solution.

 

It's going to be cluttery anyways.

 

Maybe there's something I don't know about preg_replace (very possible) but I don't know how it would be used. It's not like I can just search for, as an example, "class='MyClass'" and replace it, and it is not like I can search for "<a class="MyClass", etc.

Yes, you can... at least if I understand you correctly...

<?php
$text = 'piejfewoifewoifew
oijfweoifew
ijoijfeclass="MyClass"jrgkreofpoeofe</a>
efoiwejfoiewf
fewfewfewf<a class="MyClass" href="ppfjewfie">fpoeofe</a>poefopew
pofewofjewpiejfewoifewoifew
oijfweoifew
ijoijfeclass="some other class"jrgkreofpoeofe</a>
efoiwejfoiewf
fewfewfewf<a class="SOME NEW CLASS" href="ppfjewfie">fpoeofe</a>poefopew
pofewofjewpiejfewoifewoifew
oijfweoifew
ijoijfeclass="another one"jrgkreofpoeofe</a>
efoiwejfoiewf
fewfewfewf<a class="MyClass" href="ppfjewfie">fpoeofe</a>poefopew
pofewofjew';
$search[]='/<a class=".*?"/';
$search[]='/class=".*?"/';
$replace[]='<font color="red">1st SEARCH REPLACE</font>';
$replace[]='<font color="blue">2nd SEARCH REPLACE</font>';
echo preg_replace($search, $replace, $text);
?>

Link to comment
Share on other sites

Really appreciate the timely responses from both of you.

Unfortunately, I'm still unsure of the solutions.

$pattern = '~([href|title|class]+)="([a-zA-Z0-9:/.,; ]+)"~';
$string = '<a href="http://phpfreaks.com" title="Coding Freaks" class="myClass">Don\'t click here, it is addicting</a>';
preg_match_all($pattern,$string,$matches);

Very nice way of getting the attributes into an array. But how would I get the string? (Other than going character-by-character from each <a to >

 

$search[]='/class=".*?"/';

Wouldn't this replace the class in the div? (which, of course, I don't want to do)

 

You have both gotten me into learning more about preg_replace; preg_match - something I should have done a long time ago.

I finally went to a JavaScript solution:

$IntroText = str_replace('<a','<a onclick="Lightview.show({ href: this.href, rel: \'iframe\', title: this.title, options: {fullscreen: true }}); return false;"',$IntroText);

I tried this earlier, but there was a conflict between the href and the onclick. Adding "return false" solved that.

So a link comes out looking something like this:

<a onclick="Lightview.show({ href: this.href, rel: 'iframe', title: this.title, options: {fullscreen: true }}); return false;" href="http://www.godzilla.com" title="Godzilla">Godzilla on the Web</a>

A bonus is the link is still there, which degrades nicely if someone has JavaScript turned off.

 

Thanks again. Your help is very much appreciated.

I would still like to know if my 2 comments above, pertaining to your solutions, are off base or not.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.