rocksfrow Posted July 20, 2008 Share Posted July 20, 2008 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. Quote Link to comment Share on other sites More sharing options...
effigy Posted July 21, 2008 Share Posted July 21, 2008 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> Quote Link to comment Share on other sites More sharing options...
rocksfrow Posted July 21, 2008 Author Share Posted July 21, 2008 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 Quote Link to comment Share on other sites More sharing options...
rocksfrow Posted July 21, 2008 Author Share Posted July 21, 2008 oops, what were you trying to accomplish with this code? i'm sort of confused by what you're doing..i'm trying to COMPLETELY IGNORE any spans that don't have id="edit_text_x" do i make sense? Quote Link to comment Share on other sites More sharing options...
effigy Posted July 21, 2008 Share Posted July 21, 2008 By ignore do you mean not strip? Only strip span tags that do not have id="edit_text_x"? Quote Link to comment Share on other sites More sharing options...
rocksfrow Posted July 21, 2008 Author Share Posted July 21, 2008 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> Quote Link to comment Share on other sites More sharing options...
effigy Posted July 21, 2008 Share Posted July 21, 2008 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? Quote Link to comment Share on other sites More sharing options...
rocksfrow Posted July 21, 2008 Author Share Posted July 21, 2008 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 Quote Link to comment Share on other sites More sharing options...
effigy Posted July 21, 2008 Share Posted July 21, 2008 You could parse the HTML into a tree, but I'm not sure what PEAR has to offer. Can you use Perl? I'll ponder this one. Quote Link to comment Share on other sites More sharing options...
rocksfrow Posted July 22, 2008 Author Share Posted July 22, 2008 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? Quote Link to comment Share on other sites More sharing options...
rocksfrow Posted July 22, 2008 Author Share Posted July 22, 2008 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> Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.