0

I'm trying to get my PHP code to remove class="something" from links that contain the attribute data-class="false" and leave other links alone.

$mytext = 'text text text <a href="/url" data-class="false" class="something">
link1</a> text text text <a href="/url" class="something">link2</a> text text 
text <a href="/url" class="something" data-class="false">link3</a> text text 
text';

// This function is supposed to remove the class="something" string from matches.
function remove_class($matches) {
  return str_replace(' class="something"','', $matches[1]);
}

// Match any link that contains the data-class="false" string and do callback.
$mytext = preg_replace_callback('/<a.*?data-class="false".*?>/', 
'remove_class', $mytext);

echo $mytext;

Desired result below: (Notice the class is removed where data-class="false" exists)

text text text <a href="/url" data-class="false">link1</a> text text text
<a href="/url" class="something">link2</a> text text text
<a href="/url" data-class="false">link3</a> text text text
C-Dog
  • 125
  • 9

2 Answers2

0

this should work

$mytext = 'text text text <a href="/url" data-class="false" class="something">
link1</a> text text text <a href="/url" class="something">link2</a> text text 
text <a href="/url" class="something" data-class="false">link3</a> text text 
text';     
$mytext2=  str_replace('data-class="false" class="something"','data-class="false"', $mytext );
$mytext3=  str_replace('class="something" data-class="false"','data-class="false"', $mytext2 );
echo htmlentities($mytext3);
  • Did you try it yourself? That seems to give these results: text text text link1 text text text link2 text text text link3 text text text – C-Dog Nov 09 '13 at 07:26
  • No, that's not going to work... looking for 'class="something" data-class="false"' is not going to be robust enough... there will be other attributes in the link tag, like name, id, rel, etc... I can't guarantee that these will be together like this. – C-Dog Nov 09 '13 at 08:22
0

From the code you are showing I am not seeing a reason to use preg_replace_callback, preg_replace should be sufficient.

$mytext = 'text text text <a href="/url" data-class="false" class="something">
link1</a> text text text <a href="/url" class="something">link2</a> text text 
text <a href="/url" class="something" data-class="false">link3</a> text text 
text';

// Match any link that contains the data-class="false" and class="something" 
// Then removes class="something".
$mytext = preg_replace('/(<a.*?)(class="something")\s(.*?data-class="false".*?>)|(<a.*?)(data-class="false".*?)\s(class="something")(.*?>)/', 
'$1$3$4$5$7', $mytext);

echo $mytext;

Will Output:

text text text <a href="/url" data-class="false">
link1</a> text text text <a href="/url" class="something">link2</a> text text 
text <a href="/url" data-class="false">link3</a> text text 
text

Whats going on is that preg_replace matches class="something" data-class="false" OR data-class="false" class="something". Each sub-pattern (...) can be referenced by $ and number of the sub-pattern. If our first three sub-patterns are found then we use $1$3 leaving out $2, replacing the match with only the sub-pattern matches that we want. Since sub-patterns $4-$7 our not used they are ignored and vise versa if we match $4-$7. By leaving \s out of the sub-pattern we will be getting rid of and extra space.

hcoat
  • 2,633
  • 1
  • 22
  • 29
  • Did you try this yourself? I want to remove the class="something" part, but only if the link contains data-class="false". – C-Dog Nov 09 '13 at 07:35
  • Sorry, I was a little quick in my response. it has been updated. – hcoat Nov 09 '13 at 07:41
  • Seems close, but it did not fully work... I just tried it and this is what it gave: text text text link1 text text text link2 text text text link3 text text text – C-Dog Nov 09 '13 at 15:13
  • It only seems to work when class="something" is first, but in this case no one case be sure that class="something" will come before data-class="false"... so it needs to work no matter the order. – C-Dog Nov 09 '13 at 15:19
  • @ChrisPaddison Apperently having a return in line does not work. which I added to make more readable on `so`. I have fixed the above code. Here is working link: http://www.tehplayground.com/#PHuoNHXj6 – hcoat Nov 09 '13 at 18:33