Jump to content

matching and replacing nested span tags


rocksfrow

Recommended Posts

Okay so I've come across issues trying primarily strip specific span tags..

 

by specific i mean only span tags who have an id starting with edit_text_

 

therefore i came up with

 

/<span id="edit_text_[0-9]+"[^>]*>(.*?)<\/span>/is/

 

BUT in the case of a span tag within a span tag, or in my case i need to be prepared for even span tags within span tags within span tags  ??? heh

 

so as you could guess you'll end up with match results like:

 

so if your text is something like: 'this is the text that is editted'

 

you could end up with something like this:

 

<span id="edit_text_1">this is the <span id="edit_text_2">text</span>

 

when really what you wanted was two results:

 

<span id="edit_text_1">this is the text that is editted</span>

<span id="edit_text_2">text</span>

 

 

basically i need to match the spans starting inside out i would guess? this is only part of my problem but with a resolution for this i could probably solve the rest.

 

 

thanks in advance.

Link to comment
Share on other sites

Try this:

 

<pre>
<?php
$data = <<<DATA
ABC
<span id="edit_text_1">this is the text that is editted</span>
<span id="edit_text_2">text</span>
<span>1<span id="edit_text_3">2</span>3</span>
XYZ
DATA;
echo htmlspecialchars($data);
echo '<hr>';

$pieces = preg_split('/(?=<span id="edit_text_)/', $data, -1, PREG_SPLIT_NO_EMPTY);
$count = count($pieces);
for ($i = 0; $i < $count; $i++) {
	$pieces[$i] = preg_replace('%<span id="edit_text_[^>]+>.*?</span>%', '', $pieces[$i]);
	if (trim($pieces[$i]) == '') {
		unset($pieces[$i]);
	}
}

echo htmlspecialchars(join('', $pieces));
?>
</pre>

Link to comment
Share on other sites

hey thanks effigy but the results aren't what i expected:

 

ABC
<span id="edit_text_1">this is the text that is editted</span>
<span id="edit_text_2">text</span>
<span>1<span id="edit_text_3">2</span>3</span>
XYZ
-------------------------------------------
ABC

<span>13</span>
XYZ

Link to comment
Share on other sites

Ah I think you misunderstood me, or perhaps I explained wrong. I want to leave all tags alone EXCEPT <span id="edit_text_1"> get me?

 

So I want to end up with a string that has all other html existing, but only replace span tags with the text WITHIN the tag..don't strip out the whole thing just the actual TAG, leave the inner TEXT.

 

so if i have:

 

<span id="edit_text_1">this is my text that goes <span>here</span> and the <span id="edit_text_2">sun is orange</span> today</span>

 

i would end up with:

 

this is my text that goes <span>here</span> and the sun is orange today

 

thats the basic idea..and also on another note.. how to get these spans into an array like:

 

[0] => <span id="edit_text_1">this is my text that goes <span>here</span> and the sun is orange today</span>

[1] => <span id="edit_text_2">sun is orange</span>

 

 

 

 

Link to comment
Share on other sites

Changing

$pieces[$i] = preg_replace('%<span id="edit_text_[^>]+>.*?</span>%', '', $pieces[$i]);

to

$pieces[$i] = preg_replace('%<span id="edit_text_[^>]+>(.*?)</span>%', '$1', $pieces[$i]);

will come closer, but still not function fully. Perhaps you can do something similar to nested quotes here?

Link to comment
Share on other sites

man this is of no help what so ever..anybody else have any ideas?

 

I need to match spans correctly..basically like parsing the html tags appropriately..

 

let me say this as simple as possible

 

i need to be able to REMOVE the surrounding span in:

 

<span id="edit_text_1">one two <span id="edit_text_2">three</span> four</span>

 

BUT leaving the spans inside fine..if you did the regular expression effigy recommended you would obviously end up with:

 

one two four</span>

 

i need to end up with:

 

one two <span id="edit_text_2">three</span> four

 

 

SOMEBODY PLEASE :)

 

Link to comment
Share on other sites

okay so i jumped out of bad at 12 am because i had one of those ideas that hit me..i've come up with a function to remove span tag from by ID

 

function stripSpanById($id, $data){

  //if id doesnt exist then return unreplaced
  if(!preg_match('/<span.*?id="'.$id.'"[^>]*>/is', $data)){
    return $data;
  }

  $replace = '/<span.*?id="'.$id.'"[^>]*>/is';
  $str = preg_split($replace, $data);

  for($i=1;$i<count($str); $i++){
    $string .= $str[$i];
  }

  $str = explode('</span>', $string);

  $go = true;
  $i=0;
  $sc=0;

  while($go){
    if(preg_match('/<span[^>]*>/is', $str[$i])){

      //nested span(s), how many?
      preg_match_all('/<span[^>]*>/is', $str[$i], $nested);

      $namt = count($nested[0]);
      $sc += $namt;
      //keep the first span
      $keep .= $str[$i] . '</span>';
      if($namt > 1){
        //there are multiples, look forward and gather the rest
        for($x=1; $x<$namt; $x++){
          $keep .= $str[$i+$x] . '</span>';
          if(preg_match('/<span[^>]*>/is', $str[$i+$x])){
            preg_match_all('/<span[^>]*>/is', $str[$i+$x], $tnested);
            if(count($tnested[0] > 1)){
              $sc += count($tnested[0]);
            }else {
              $sc++;
            }
          }
}
        $i = $i + $namt;

      }else {
        //only one, easy
$i++;
      }
    }else {
      //ending span, finish
      $keep .= $str[$i];
      if($sc > 0 && ((count(explode('</span>', $keep))-1) < ($sc))){
$keep .= '</span>';
$i++;
      }else {
$go = false;
      }
    }
  }
  //now replace the whole string with only the inner text
  $match = '/<span id="'.$id.'"[^>]*>/is';
  preg_match($match, $data, $keepmatch);

  //return the replaced value
  return str_replace($keepmatch[0] . $keep . '</span>', $keep, $data);

}

 

i wrote this function myself...took a lot of tweaking/testing so i would LOVE if somebody could look through and look for obvious no nos..i've tested multiple instances and results have been perfect:

 

 

$data before replace:

 

<span id="edit_text_9">

<span id="edit_text_1">this <span>is</span> <span>the <span id="edit_text_3">text <span>here</span> <span id="edit_text_5">here here</span> here here</span> that is</span> editted</span>

<span id="edit_text_2">text</span>

<span>1<span id="edit_text_4">2</span>3</span>

</span>

 

<span>blah <span>blah blah <span>blah <span id="test">blah</span> blah</span> blah</span></span>

 

$data = stripSpanById('test', $data);

 

$data after replace:

 

<span id="edit_text_9">

<span id="edit_text_1">this <span>is</span> <span>the <span id="edit_text_3">text <span>here</span> <span id="edit_text_5">here here</span> here here</span> that is</span> editted</span>

<span id="edit_text_2">text</span>

<span>1<span id="edit_text_4">2</span>3</span>

</span>

 

<span>blah <span>blah blah <span>blah blah blah</span> blah</span></span>

 

 

please play with it..can you find a situation it doesnt work?

Link to comment
Share on other sites

heh, actually that example usage i showed could have been done with an easy regex..heres the power of it:

 

<span id="edit_text_9">

<span id="edit_text_1">this <span>is</span> <span>the <span id="edit_text_3">text <span>here</span> <span id="edit_text_5">here here</span> here here</span> that is</span> editted</span>

<span id="edit_text_2">text</span>

<span>1<span id="edit_text_4">2</span>3</span>

</span>

 

<span>blah <span>blah blah <span>blah <span id="test">blah</span> blah</span> blah</span></span>

 

 

$data = stripSpanById('edit_text_3', $data);

 

 

<span id="edit_text_9">

<span id="edit_text_1">this <span>is</span> <span>the text <span>here</span> <span id="edit_text_5">here here</span> here here that is</span> editted</span>

<span id="edit_text_2">text</span>

<span>1<span id="edit_text_4">2</span>3</span>

</span>

 

<span>blah <span>blah blah <span>blah <span id="test">blah</span> blah</span> blah</span></span>

 

 

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.