2014-03-19 49 views
0

我想要使用PHP刪除表內的所有<br />。我知道我可以使用str_replace()刪除<br />。但它會刪除所有<br />。我只想刪除<table></table>之間的<br />。我有一個字符串中的幾個表。使用PHP刪除<br />表內使用PHP

html代碼如下。你也可以看到this fiddle

<p>Some text before table:</p><table cellpadding="0" cellspacing="0"><br /> <tbody><br />  <tr><br />   <td><br />   <p><strong>column1</strong></p>   </td><br />   <td><br />   <p><strong>column2</strong></p>   </td></tr><br />  <tr><br />   <td><br />   <p>1</p>   </td><br />   <td><br />   <p>2</p>   </td><br />   <br />  </tr><br /> </tbody><br /></table> 

<p>Some text before table:</p><table cellpadding="0" cellspacing="0"><br /> <tbody><br />  <tr><br />   <td><br />   <p><strong>column1</strong></p>   </td><br />   <td><br />   <p><strong>column2</strong></p>   </td></tr><br />  <tr><br />   <td><br />   <p>1</p>   </td><br />   <td><br />   <p>2</p>   </td><br />   <br />  </tr><br /> </tbody><br /></table> 

我試過以下方法來做到這一點,這是最好的解決方案嗎?

<?php 
    $input = '<p>Some text before table:</p><table cellpadding="0" cellspacing="0"><br /> <tbody><br />  <tr><br />   <td><br />   <p><strong>column1</strong></p>   </td><br />   <td><br />   <p><strong>column2</strong></p>   </td></tr><br />  <tr><br />   <td><br />   <p>1</p>   </td><br />   <td><br />   <p>2</p>   </td><br />   <br />  </tr><br /> </tbody><br /></table> 

<p>Some text before table:</p><table cellpadding="0" cellspacing="0"><br /> <tbody><br />  <tr><br />   <td><br />   <p><strong>column1</strong></p>   </td><br />   <td><br />   <p><strong>column2</strong></p>   </td></tr><br />  <tr><br />   <td><br />   <p>1</p>   </td><br />   <td><br />   <p>2</p>   </td><br />   <br />  </tr><br /> </tbody><br /></table>'; 


$body = preg_replace_callback("~<table\b.*?/table>~si", "process_table", $input); 

function process_table($match) { 

     return str_replace('<br />', '', $match[0]); 

} 

echo $body; 
+0

使用正則表達式使用了preg_replace() – Oyeme

+0

用簡單的正則表達式的問題就可以了,你什麼時候桌子裏有桌子。你有餐桌嗎? –

+1

什麼產生你的無效HTML? – j08691

回答

1

正如here所述,「正則表達式不是一個可以用來正確解析HTML的工具」。但是,爲了提供一個解決方案,要求爲這個受控案例工作,我提交以下內容。它包含顯示前後的調試代碼。

注:我也跟你的正則表達式測試,它的工作原理以及與/<table\b.*?<\/table>/sipreg_match()

<?php 

$search ='<p>Some text before table:</p><table cellpadding="0" cellspacing="0"><br /> <tbody><br />  <tr><br />   <td><br />   <p><strong>column1</strong></p>   </td><br />   <td><br />   <p><strong>column2</strong></p>   </td></tr><br />  <tr><br />   <td><br />   <p>1</p>   </td><br />   <td><br />   <p>2</p>   </td><br />   <br />  </tr><br /> </tbody><br /></table> 

<p>Some text before table:</p><table cellpadding="0" cellspacing="0"><br /> <tbody><br />  <tr><br />   <td><br />   <p><strong>column1</strong></p>   </td><br />   <td><br />   <p><strong>column2</strong></p>   </td></tr><br />  <tr><br />   <td><br />   <p>1</p>   </td><br />   <td><br />   <p>2</p>   </td><br />   <br />  </tr><br /> </tbody><br /></table>'; 

$search = replacebr($search); 

function replacebr($search){ 
     $offset=0; 
     $anew=array(); 
     $asearch=array(); 
     $notdone = 1; 
     $i=0; 

    echo $search; 

     while ($notdone == 1) { 
      ($notdone = preg_match('/<table\s[^>]*>(.+?)<\/table>/', $search, $amatch, PREG_OFFSET_CAPTURE, $offset)); 
      if (count($amatch)>0){ 
echo "amatch: " ; var_dump($amatch); 
       // add part before match 
       $anew[] = substr($search,$offset,$amatch[0][1]-$offset); 

echo "anew (before): " ; var_dump($anew[count($anew)-1]); 
       // add match with replaced text 
       $anew[] = str_replace("<br />","",$amatch[0][0]); 
echo "anew (match): " ; var_dump($anew[count($anew)-1]); 

       $offset += mb_strlen(substr($search,$offset,$amatch[0][1]-$offset))+ mb_strlen($amatch[0][0]); 
echo "OFFSET: " ; var_dump($offset); 

      } 
      else{ 
       // add last part of string - we better be done 
       $anew[] = substr($search, $offset); 
       $search==""; 
       if ($notdone == 1){ 
        die("Error - should be done"); 
       } 
      } 
      if ($i==100){ 
       // prevent endless loop 
       die("Endless Loop"); 
      } 
      $i++; 
     } 
     $new = implode("",$anew); 
      echo "*******************"; 
      echo $new; 
     return $new; 
    } 


?> 
+0

+1對於bobince大喊大叫 – Phlume

0

不要建議來解析與正則表達式的HTML,但如果你有
這可能工作。

注 - 測試用例在Perl中,但正則表達式將在PHP中工作。
就全球與$1

# '~(?s)((?:(?!\A|<table\b)\G|<table\b)(?:(?!<br\s*/>|</table\b).)*)<br\s*/>(?=.*?</table\b)~' 

(?s)       # Dot-All 
(       # (1 start), Keep these 
     (?: 
      (?! \A | <table \b) 
      \G       # Start match from end of last match 
     |        # or, 
      <table \b     # Start form '<table\b' 
    ) 
     (?:       # The chars before <br/ or </table end tags 
      (?! 
       <br \s* /> 
      | </table \b 
      ) 
      . 
    )* 
)       # (1 end) 
<br \s* />     # Strip <br/> 
(?= .*? </table \b)   # Must be </table end tag downstream 

Perl的測試用例更換

$/ = undef; 

$str = <DATA>; 

print "Before:\n$str\n\n"; 
$str =~ s~(?s)((?:(?!\A|<table\b)\G|<table\b)(?:(?!<br\s*/>|</table\b).)*)<br\s*/>(?=.*?</table\b)~$1~g; 
print "After:\n$str\n\n"; 

__DATA__ 
<p>Some text before table:</p><table cellpadding="0" cellspacing="0"><br /> <tbody><br />  <tr><br />   <td><br />   <p><strong>column1</strong></p>   </td><br />   <td><br />   <p><strong>column2</strong></p>   </td></tr><br />  <tr><br />   <td><br />   <p>1</p>   </td><br />   <td><br />   <p>2</p>   </td><br />   <br />  </tr><br /> </tbody><br /></table> 

輸出>>

Before: 
<p>Some text before table:</p><table cellpadding="0" cellspacing="0"><br /> <tbody><br />  <tr><br />   <td><br />   <p><strong>column1</strong></p>   </td><br />   <td><br />   <p><strong>column2</strong></p>   </td></tr><br />  <tr><br />   <td><br />   <p>1</p>   </td><br />   <td><br />   <p>2</p>   </td><br />   <br />  </tr><br /> </tbody><br /></table> 

After: 
<p>Some text before table:</p><table cellpadding="0" cellspacing="0"> <tbody>  <tr>   <td>   <p><strong>column1</strong></p>   </td>   <td>   <p><strong>column2</strong></p>   </td></tr>  <tr>   <td>   <p>1</p>   </td>   <td>   <p>2</p>   </td>    </tr> </tbody></table>