2 回答
TA贡献1773条经验 获得超3个赞
不要使用正则表达式来解析 HTML。
您有一个简单的目标:将文本内容限制为给定的字数,确保 HTML 保持有效。
为此,我建议循环遍历文本节点,直到您计算出一定数量的单词,然后删除之后的所有内容。
$dom = new DOMDocument();
$dom->loadHTML($post_content);
$xpath = new DOMXPath($dom);
$all_text_nodes = $xpath->query("//text()");
$words_left = 48;
foreach( $all_text_nodes as $text_node) {
$text = $text_node->textContent;
$words = explode(" ", $text); // TODO: maybe preg_split on /\s/ to support more whitespace types
$word_count = count($words);
if( $word_count < $words_left) {
$words_left -= $word_count;
continue;
}
// reached the threshold
$words_that_fit = implode(" ", array_slice($words, 0, $words_left));
// If the above TODO is implemented, this will need to be adjusted to keep the specific whitespace characters
$text_node->textContent = $words_that_fit;
$remove_after = $text_node;
while( $remove_after->parentNode) {
while( $remove_after->nextSibling) {
$remove_after->parentNode->removeChild($remove_after->nextSibling);
}
$remove_after = $remove_after->parentNode;
}
break;
}
$output = substr($dom->saveHTML($dom->getElementsByTagName("body")->item(0)), strlen("<body>"), -strlen("</body>"));
TA贡献1846条经验 获得超7个赞
好的,我想出了一个解决方法。我不知道这是否是最优雅的解决方案,所以如果有人看到更好的解决方案,我仍然很想听听,但现在我意识到我不必在我正在搜索的字符串中实际包含 html确定切割的位置,我只需要它是相同的长度。我抓取了所有的 html 元素,并创建了一个虚拟字符串,用相同数量的星号替换了所有元素:
// create faux string with placeholders instead of html for search purposes
preg_match_all('/<\/?[^>]*>/', $post_content, $alltags_result);
$tagcount = count( $alltags_result );
$post_content_dummy = $post_content;
foreach($alltags_result[0] as $thistag){
$post_content_dummy = str_replace($thistag, str_repeat("*",strlen($thistag)), $post_content_dummy);
}
然后我只是$post_content_dummy在 while 循环中使用而不是$post_content,以便找到切割位置,然后$post_content进行实际切割。到目前为止似乎工作正常。
- 2 回答
- 0 关注
- 133 浏览
添加回答
举报