2011-09-15 46 views
4

編輯:截斷HTML文本,同時考慮到 「句號」(在CachePHP TextHelper->截斷)

最後我用CakePHP的truncate()功能。它的速度更快,並支持Unicode:d

但問題依然存在:

如何使功能自動檢測句號(.),只是之後下調嗎?所以基本上$length將被半被忽略。因此,如果新文本將有一個不完整的句子,多的話會追加到句子結束(或刪除,這取決於從截止字符串的長度,直到下一個/前面的句子)

編輯2: 我發現如何檢測句號。我換成:

if (!$exact) { 
    $spacepos = mb_strrpos($truncate, ' '); 

... 

if (!$exact) { 
    $spacepos = mb_strrpos($truncate, '.'); 
... 

編輯 - 問題:

當我有標籤,如img有其屬性裏面點,文本獲取標籤內截止:

$text = '<p>Abc def abc def abc def abc def. Abc def <img src="test.jpg" /></p><p>abc def abc def abc def abc def.</p>'; 

echo htmlentities(truncate($text)); 

我該如何解決是什麼?我會打開一個賞金,因爲原來的問題已經得到解答...

+0

我想你只是回答你的問題。因此,您可以繼續添加新詞,直到找到「。」。並且還會從計算文本中減去單詞,直到找到「。」。然後比較長度並選擇好的一個。當你這樣做後,嘗試優化:) –

+0

嘿!我想我已經回答了您的原始問題,但我很高興您找到了解決方案!我正在研究Rails'truncate'方法的源代碼,它提供了與您正在尋找的功能非常相似的功能。 – Alex

+0

感謝Alex,你能發佈一個鏈接到Rails函數嗎? – Alex

回答

5

This snippet解決你在找什麼,並列出它的失敗(句號可能不是句子結束,其他標點符號可以結束句子)。

它將掃描最多$maxLen的字符,然後在找到最後一個句號後有效地「拋棄」部分句子。

就您而言,您只需在返回$new_text之前使用此功能。

2

要解決的「全停在標籤」的問題,你可以使用類似下面來檢測,如果該站是一個標籤內:

$str_len  = strlen($summary); 
$pos_stop  = strrpos($summary, '.'); 
$pos_tag_open = strrpos($summary, '<', -($str_len - $pos_stop)); 
$pos_tag_close = strpos($summary, '>', $pos_tag_open); 

if (($pos_tag_open < $pos_stop) && ($pos_stop < $pos_tag_close)) { 
    // Inside tag! Search for the next nearest prior full-stop. 
    $pos_stop = strrpos($summary, '.', -($str_len - $pos_tag_open)); 
} 

echo htmlentities(substr($summary, 0, $pos_stop + 1)); 

顯然,這個代碼可以優化(和拉出自己的功能),但你明白了。我有一種感覺,有一個正則表達式可以更有效地處理這個問題。

編輯:

事實上,正則表達式可以做到這一點,使用負前瞻:

$text = '<p>Abc def abc def abc def abc def. Abc def <img src="test.jpg" />abc</p>'; 

$count = preg_match_all("/\.(?!([^<]+)?>)/", $text, $arr, PREG_OFFSET_CAPTURE); 
$offset = $arr[0][$count-1][1]; 

echo substr($text, 0, $offset + 1)."\n"; 

這應該是比較有效的,至少與truncate()也是其中比較內部使用preg_match。

+0

上面的正則表達式可能有效。但是,考慮到效率,在這種情況下,我們可能會首先將字符串截斷爲max_length,然後對截斷的字符串執行preg。是的,必須考慮標點符號。 – acpmasquerade

+0

@acpmasquerade - 意圖是,在truncate()後面運行正則表達式,以便在最大字符數限制之前查找最早可能的句子結束。預先使用正則表達式是毫無意義的,因爲在將字符串截斷爲長度時結果會丟失。 –

1

上面的Truncate html text while taking in consideration "full stops" (in CachePHP TextHelper->truncate)正則表達式可能有效。

但是,考慮到效率,在這種情況下,我們可能會截斷字符串到MAX_LENGTH第一,然後做預浸到截斷的字符串。是的,必須考慮標點符號。

一些更多的規則將創建一個適當的邏輯來確定句子的結尾。

  1. 的空間或拾取標點後
  2. 第一個字的標點符號後一個EOL,具有一上部外殼。
  3. 標點符號等後的多個新行(段尾)