2013-08-20 70 views
0

我使用此php代碼大致每120個字符分割一個字符串。它在最近的空間分裂。但它分割HTML和XML實體,所以它有時會輸出像id="id">這樣的東西。我怎樣才能讓它忽略XML和HTML實體,但不會刪除它們。preg_split但忽略XML和HTML實體

function splitWords($string, $max = 1) 
{ 
    $words = preg_split('/\s/', $string); 
    $lines = array(); 
    $line = ''; 

    foreach ($words as $k => $word) { 
     $newLine = $line . ' ' . $word; 
     $length = strlen($newLine); 
     if ($length <= $max) { 
      $line .= ' ' . $word; 
     } else if ($length > $max) { 
      if (!empty($line)) { 
       $lines[] = trim($line); 
      } 
      $line = $word; 
     } else { 
      $lines[] = trim($line) . ' ' . $word; 
      $line = ''; 
     } 
    } 
    $lines[] = ($line = trim($line)) ? $line : $word; 

    return $lines; 
} 
+0

有另一種達到相同結果的方式? – rob

+3

也許你可以使用[DOMDocument](http://www.php.net/manual/en/domdocument.loadhtml.php)並遍歷它? – Wiktor

+2

什麼?因爲如果是電子郵件,[這是'quuoted_printable_encode()'用於](http://php.net/manual/en/function.quoted-printable-encode.php) – Wrikken

回答

1

說明

我會改變你的拆分命令來使用標籤字符串作爲分隔符或空格。

這個基本的正則表達式會:

  • 匹配的標籤或將匹配空間
  • 它不會匹配的標記內部空間
  • 將避免很多陷阱與模式匹配的HTML文本

<\/?\w+(?=\s|>)(?:[^>=|&)]*|=\'[^\']*\'|="[^"]*"|=[^\'"][^\s>]*)*>|\s

enter image description here

有了這個正則表達式,你可以做各種瘋狂的事情,這取決於你在哪裏放置捕捉paranthesse和preg_split中使用的選項。

例子

Live Demo

注意,在這個演示錨標籤有一些嚴重的困難的邊緣情況。

PHPv5.4.4代碼

<?php 

$string = ' <a onmouseover=\' <a href="notreal.com">This is text inside an attribute</a> \' href=url.com>This is some inner text</a>This is outer text. 

    <a onmouseover=\' a=1; href="www.NotYourURL.com" ; if (3 <a && href="www.NotYourURL.com" && id="revSAR" && 6 > 3) { funRotate(href) ; } ; \' href=\'http://InterestedURL.com\' id=\'revSAR\'> 
     I am the inner text too. 
     </a> 
'; 

echo "split retains all spaces\n"; 
$array = preg_split ('/(<\/?\w+(?=\s|>)(?:[^>=|&)]*|=\'[^\']*\'|="[^"]*"|=[^\'"][^\s>]*)*>|\s)/', $string, 0, PREG_SPLIT_DELIM_CAPTURE); 
echo implode(",",$array); 

echo "\n\nsplit ignores spaces\n"; 
$array = preg_split ('/(<\/?\w+(?=\s|>)(?:[^>=|&)]*|=\'[^\']*\'|="[^"]*"|=[^\'"][^\s>]*)*>)|\s/', $string, 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); 
echo implode(",",$array); 

echo "\n\nsplit ignores tags and spaces\n"; 
$array = preg_split ('/<\/?\w+(?=\s|>)(?:[^>=|&)]*|=\'[^\']*\'|="[^"]*"|=[^\'"][^\s>]*)*>|\s/', $string, 0, PREG_SPLIT_NO_EMPTY); 
echo implode(",",$array); 

echo "\n\nsplit ignores tags and retains spaces\n"; 
$array = preg_split ('/<\/?\w+(?=\s|>)(?:[^>=|&)]*|=\'[^\']*\'|="[^"]*"|=[^\'"][^\s>]*)*>|(\s)/', $string, 0, PREG_SPLIT_DELIM_CAPTURE); 
echo implode(",",$array); 

輸出

你可能最感興趣的是第三個選項 「分裂忽略標籤和空格」

split retains all spaces 
, ,,<a onmouseover=' <a href="notreal.com">This is text inside an attribute</a> ' href=url.com>,This, ,is, ,some, ,inner, ,text,</a>,This, ,is, ,outer, ,text., 
,, 
,, ,,<a onmouseover=' a=1; href="www.NotYourURL.com" ; if (3 <a && href="www.NotYourURL.com" && id="revSAR" && 6 > 3) { funRotate(href) ; } ; ' href='http://InterestedURL.com' id='revSAR'>,, 
,, ,, ,I, ,am, ,the, ,inner, ,text, ,too., 
,, ,, ,,</a>,, 
, 

split ignores spaces 
<a onmouseover=' <a href="notreal.com">This is text inside an attribute</a> ' href=url.com>,This,is,some,inner,text,</a>,This,is,outer,text.,<a onmouseover=' a=1; href="www.NotYourURL.com" ; if (3 <a && href="www.NotYourURL.com" && id="revSAR" && 6 > 3) { funRotate(href) ; } ; ' href='http://InterestedURL.com' id='revSAR'>,I,am,the,inner,text,too.,</a> 

split ignores tags and spaces 
This,is,some,inner,text,This,is,outer,text.,I,am,the,inner,text,too. 

split ignores tags and retains spaces 
, ,,This, ,is, ,some, ,inner, ,text,This, ,is, ,outer, ,text., 
,, 
,, ,,, 
,, ,, ,I, ,am, ,the, ,inner, ,text, ,too., 
,, ,, ,,, 
, 
+1

不!不REGEX和HTML! –

+0

@Cole「Cole9」約翰遜是否因此而失望?你有什麼具體的測試案例,哪裏失敗? –

+0

是的,很容易找到這個失敗的測試用例 –