使用约束将字符串拆分为较小的部分[PHP RegEx HTML]

时间:2010-04-28 09:40:45

标签: php regex string split html-parsing

我需要将长字符串拆分为具有以下约束的数组:

  • 输入将是HTML字符串,可能是整页或部分。
  • 每个部分(新字符串)的字符数量有限(例如不超过8000个字符)
  • 每个部分可以包含多个句子(由。[句号]分隔)但从不是部分句子除非字符串的最后部分(因为最后一部分可能没有任何句号。
  • 该字符串包含HTML标记。但标签不能分为<a href='test.html'><a href='test。和html'>)。这意味着HTML标签应该完好无损。 但是,开始标记和结束标记可以保留在不同的段/块
  • 如果任何中间句子大于所需长度,则前导和尾随标记以及空格应位于数组的不同部分。即使这样做,如果句子较长,则将其分成数组的多个元素:(
  • 请注意:无需解析HTML但标签(如或等)&lt;。*&gt;

我认为使用preg_split的正则表达式可以做到这一点。请帮助我使用正确的RegEx。除了正则表达式之外的任何解决方案也欢迎。

谢谢

萨迪

2 个答案:

答案 0 :(得分:1)

如果我错了,请纠正我,但我不认为你可以通过一个简单的正则表达式来做到这一点。在完整的正则表达式实现中,您可以使用以下内容:

$parts = preg_split("/(?<!<[^>]*)\./", $input);

但是php不允许非固定长度的lookbehind,所以这不起作用。显然,唯一的两个是jgsoft和.net regexp。 Useful Page

我处理这个问题的方法是:

function splitStringUp($input, $maxlen) {
    $parts = explode(".", $input);
    $i = 0;
    while ($i < count($parts)) {
        if (preg_match("/<[^>]*$/", $parts[$i])) {
            array_splice($parts, $i, 2, $parts[$i] . "." . $parts[$i+1]);
        } else {
            if ($i < (count($parts) - 1) && strlen($parts[$i] . "." . $parts[$i+1]) < $maxlen) {
                array_splice($parts, $i, 2, $parts[$i] . "." . $parts[$i+1]);
            } else {
                $i++;
            }
        }
    }
    return $parts;
}

当你的单个句子长度超过8000个字符时,你没有提到你想要发生什么,所以这只会让它们完整无缺。

示例输出:

splitStringUp("this is a sentence. this is another sentence. this is an html <a href=\"a.b.c\">tag. and the closing tag</a>. hooray", 8000);
array(1) {
  [0]=> string(114) "this is a sentence. this is another sentence. this is an html <a href="a.b.c">tag. and the closing tag</a>. hooray"
}

splitStringUp("this is a sentence. this is another sentence. this is an html <a href=\"a.b.c\">tag. and the closing tag</a>. hooray", 80);
array(2) {
  [0]=> string(81) "this is a sentence. this is another sentence. this is an html <a href="a.b.c">tag"
  [1]=> string(32) " and the closing tag</a>. hooray"
}

splitStringUp("this is a sentence. this is another sentence. this is an html <a href=\"a.b.c\">tag. and the closing tag</a>. hooray", 40);
array(4) {
  [0]=> string(18) "this is a sentence"
  [1]=> string(25) " this is another sentence"
  [2]=> string(36) " this is an html <a href="a.b.c">tag"
  [3]=> string(32) " and the closing tag</a>. hooray"
}

splitStringUp("this is a sentence. this is another sentence. this is an html <a href=\"a.b.c\">tag. and the closing tag</a>. hooray", 0);
array(5) {
  [0]=> string(18) "this is a sentence"
  [1]=> string(25) " this is another sentence"
  [2]=> string(36) " this is an html <a href="a.b.c">tag"
  [3]=> string(24) " and the closing tag</a>"
  [4]=> string(7) " hooray"
}

答案 1 :(得分:0)

不幸的是,html是不规则的语言,意味着你无法用一个正则表达式解析它。另一方面,如果输入始终相似,或者您只需要解析某些部分,那就没有问题了。对此正则表达式的迭代生成元素名称及其内容:

'~<(?P<element>\s+)(?P<attributes>[^>]*)>(?:(?P<content>.*?)</\s+>)?~'