将HTML字符串拆分为两个字符串,而无需切分单词并在PHP中保留HTML
我正在寻找一种将包含HTML的字符串拆分为两半的方法。要求:将HTML字符串拆分为两个字符串,而无需切分单词并在PHP中保留HTML,php,regex,string,Php,Regex,String,我正在寻找一种将包含HTML的字符串拆分为两半的方法。要求: 按字符数拆分字符串 不能在单词的中间分裂 在计算拆分字符串的位置时,不能包含HTML字符 例如,以以下字符串为例: 这是一个包含HTML标记和文本内容的测试字符串。这个字符串需要被分割而不通过一个词的中间部分,并且必须保持HTML的有效性,即不在标签的中间分裂,并且确保正确地关闭结束标签。 < /Cord>< /P> 假设我想在字符位置39拆分,在单词HTML(不包括HTML)的中间,我想让函数将字符串拆分为以下两部分: 这是一个
- 按字符数拆分字符串
- 在计算拆分字符串的位置时,不能包含HTML字符
这是一个包含HTML标记和文本内容的测试字符串。这个字符串需要被分割而不通过一个词的中间部分,并且必须保持HTML的有效性,即不在标签的中间分裂,并且确保正确地关闭结束标签。 < /Cord>< /P>
假设我想在字符位置39拆分,在单词HTML(不包括HTML)的中间,我想让函数将字符串拆分为以下两部分:
这是一个测试字符串,包含HTML
及
标签和文本内容。这个字符串需要被分割而不通过一个词的中间部分,并且必须保持HTML的有效性,即不在标签的中间分裂,并且确保正确地关闭结束标签。 < /Cord>< /P>
注意,在上面的两个示例结果中,我要求遵守HTML有效性,因此添加了结束标记
和
。另外,在后半部分添加了一个起始标记,作为在字符串末尾关闭的标记
我在StackOverflow上找到了这个函数,它可以将字符串截断若干个文本字符并保留HTML,但它只达到了我所需要的一半,因为我需要将字符串分成两半
function printTruncated($maxLength, $html)
{
$printedLength = 0;
$position = 0;
$tags = array();
while ($printedLength < $maxLength && preg_match('{</?([a-z]+)[^>]*>|&#?[a-zA-Z0-9]+;}', $html, $match, PREG_OFFSET_CAPTURE, $position))
{
list($tag, $tagPosition) = $match[0];
// Print text leading up to the tag.
$str = substr($html, $position, $tagPosition - $position);
if ($printedLength + strlen($str) > $maxLength)
{
print(substr($str, 0, $maxLength - $printedLength));
$printedLength = $maxLength;
break;
}
print($str);
$printedLength += strlen($str);
if ($tag[0] == '&')
{
// Handle the entity.
print($tag);
$printedLength++;
}
else
{
// Handle the tag.
$tagName = $match[1][0];
if ($tag[1] == '/')
{
// This is a closing tag.
$openingTag = array_pop($tags);
assert($openingTag == $tagName); // check that tags are properly nested.
print($tag);
}
else if ($tag[strlen($tag) - 2] == '/')
{
// Self-closing tag.
print($tag);
}
else
{
// Opening tag.
print($tag);
$tags[] = $tagName;
}
}
// Continue after the tag.
$position = $tagPosition + strlen($tag);
}
// Print any remaining text.
if ($printedLength < $maxLength && $position < strlen($html))
print(substr($html, $position, $maxLength - $printedLength));
// Close any open tags.
while (!empty($tags))
printf('</%s>', array_pop($tags));
}
函数printTruncated($maxLength,$html)
{
$printedLength=0;
$position=0;
$tags=array();
而($printedLength<$maxLength&&preg#u match('{]*>|?[a-zA-Z0-9]+}',$html,$match,preg#u OFFSET#u CAPTURE,$position))
{
列表($tag,$tagPosition)=$match[0];
//打印指向标记的文本。
$str=substr($html,$position,$tagPosition-$position);
如果($printedLength+strlen($str)>$maxLength)
{
打印(substr($str,0,$maxLength-$printedLength));
$printedLength=$maxLength;
打破
}
印刷品($str);
$printedLength+=strlen($str);
如果($tag[0]='&'))
{
//处理实体。
打印($tag);
$printedLength++;
}
其他的
{
//处理标签。
$tagName=$match[1][0];
如果($tag[1]=='/'))
{
//这是一个结束标记。
$openingTag=array\u pop($tags);
assert($openingTag==$tagName);//检查标记是否正确嵌套。
打印($tag);
}
else if($tag[strlen($tag)-2]=='/'))
{
//自动关闭标签。
打印($tag);
}
其他的
{
//开场白。
打印($tag);
$tags[]=$tagName;
}
}
//在标记之后继续。
$position=$tagPosition+strlen($tag);
}
//打印任何剩余文本。
如果($printedLength<$maxLength&&$position
几乎所有其他答案都会引用的一般规则是“不要使用正则表达式处理HTML-您无法捕获所有边缘情况”
我相信这是真的
字符串中的任何内容,即使是格式稍有错误的,甚至是最好的正则表达式,都会把它搞砸
忽略你想要拆分一些标签而不是其他标签(P标签是标签,毕竟你想把一个分割成两个),你可能需要重新思考这个过程,并且对你想要达到的目标非常具体,例如在段落标签的中间是分裂的,好吗?那divs呢?如果中间点在标记内,您希望第一个字符串更长,还是第二个字符串更长
假设拆分段落标记是可以的,但其他的则不行,请尝试以下方法:(这里没有复制粘贴代码,抱歉)
*剥离目标字符串两次-一次剥离所有标记,一次剥离段落标记
*在“无标记”字符串中找到中间点
*在中间点后的第一个空格处拆分所有字符串的无标记
*在just-p-tags-stripped字符串中找到与上一步中点后的单词匹配的位置-这应该告诉您忽略标记时just-p-tags-stripped字符串中的“中间”位置
*检查是否在标签内
。。事实上,当我说到这一点的时候,我意识到我写的90%都是非常明显的,最后一点就是问题所在
我将在这里留下我半成品的咆哮,以警告其他人和我自己。给出的答案也适用于你的问题