【问题标题】:preg_split but ignore XML and HTML entitiespreg_split 但忽略 XML 和 HTML 实体
【发布时间】:2013-08-20 13:51:53
【问题描述】:

我使用这个 php 代码大约每 120 个字符拆分一个字符串。它在最近的空间分裂。但它会拆分 HTML 和 XML 实体,因此有时会输出 id="id"> 之类的内容。我怎样才能让它忽略 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;
}

【问题讨论】:

标签: php regex php-5.4


【解决方案1】:

说明

我会更改您的拆分命令以使用标记子字符串作为分隔符或空格。

这个基本的正则表达式将:

  • 匹配标签或将匹配空格
  • 它不会匹配标签内的空格
  • 将避免许多模式匹配 html 文本的陷阱

&lt;\/?\w+(?=\s|&gt;)(?:[^&gt;=|&amp;)]*|=\'[^\']*\'|="[^"]*"|=[^\'"][^\s&gt;]*)*&gt;|\s

使用这个正则表达式,你可以根据你放置捕获括号的位置和 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.,
,,  ,,  ,,,
,

【讨论】:

  • @Cole"Cole9"Johnson 你投了反对票是因为这个原因吗?您是否有任何失败的特定测试用例?
  • 是的,很容易找到失败的测试用例
  • @JimDvorak 是的。因此,我确实投了反对票。 Here's why。严重地。回答者有 5k 代表,并建议使用正则表达式解析 HTML!
  • @Cole"Cole9"Johnson,所以它可以工作,但你只是不同意这个过程。很公平,每个人都有自己的看法。
  • @Cole"Cole9"Johnson ... 你不需要 需要 整个评论的一半 ; 将所有内容都加粗没有意义,因为那样什么都没有强调不再
猜你喜欢
  • 2010-12-29
  • 2011-05-31
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多