【问题标题】:Split string into smaller part with constrain [PHP RegEx HTML]使用约束将字符串拆分为较小的部分 [PHP RegEx HTML]
【发布时间】:2011-02-13 06:31:17
【问题描述】:

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

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

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

谢谢

萨迪

【问题讨论】:

    标签: php regex string split html-parsing


    【解决方案1】:

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

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

    但是 php 不允许非固定长度的lookbehind,所以这是行不通的。显然,仅有的两个是 jgsoft 和 .net 正则表达式。 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"
    }
    

    【讨论】:

    • 对不起!我忘记提了。我将更新这一点。
    • 看起来您的解决方案放弃了句号:P 添加句号不会有问题(我认为):)
    • 是的,只需添加一个 .到每个部分的结尾:)
    • 嗨,请您添加约束:如果任何中间句子大于所需长度,则前导和尾随标签和空格应位于数组的不同部分。即使这样做了,如果句子较长,则将其分成数组的多个元素:(
    • 我不明白你的意思,对不起。这听起来很复杂,您应该能够自己修改我的代码来完成。毕竟,它拥有你应该做的所有元素。
    【解决方案2】:

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

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

    【讨论】:

    • 其实我并不关心 HTML。我关心标签。标签以&lt; 开头,以&gt; 结尾。那就足够了。除了正则表达式之外的任何解决方案都可以。我会试试你的答案。谢谢你的时间:)
    • 哦!不要忘记每个新字符串的长度。这是最重要的部分
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多