Разбить строку на меньшую часть с ограничением [PHP RegEx HTML] - PullRequest
0 голосов
/ 28 апреля 2010

Мне нужно разбить длинную строку на массив со следующими ограничениями:

  • Ввод будет HTML-строкой , может быть полной страницей или частичной.
  • Каждая часть (новые строки) будет иметь ограниченное количество символов (например, не более 8000 символов)
  • Каждая часть может содержать несколько предложений (разделенных. [Точка]) , но не частичные предложения . За исключением случаев, когда последняя часть строки (как последняя часть может не иметь полной остановки.
  • Строка содержит теги HTML. Но тег нельзя разделить на (<a href='test.html'> до <a href='test. И html'>). Это означает, что HTML-тег должен быть неповрежденным. Но начальный тег и конечный тег могут находиться в другом сегменте / фрагменте .
  • Если какое-либо среднее предложение превышает желаемую длину, то начальные и конечные теги и пробелы должны находиться в другой части массива. Даже после этого, если предложение длиннее, разделите его на несколько элементов массива: (
  • Обратите внимание: нет необходимости анализировать HTML, кроме тегов (например, или т. Д.) <. *>

Я думаю, что регулярное выражение с preg_split может сделать это. Пожалуйста, помогите мне с правильным RegEx. Любое решение, кроме регулярных выражений также приветствуется.

Спасибо

Сади

Ответы [ 2 ]

1 голос
/ 30 апреля 2010

поправьте меня, если я ошибаюсь, но я не думаю, что вы можете сделать это с помощью простого регулярного выражения. в полной реализации регулярного выражения вы можете использовать что-то вроде этого:

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

, но php не разрешает смотреть назад не фиксированной длины, так что это не сработает. по-видимому, единственные 2, которые делают это jgsoft и .net регулярные выражения. Полезная страница

мой метод борьбы с этим будет:

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"
}
0 голосов
/ 29 апреля 2010

К сожалению, html - это нерегулярный язык, что означает, что вы не можете разобрать его с помощью одного регулярного выражения. С другой стороны, если входные данные всегда похожи или вам нужно только разобрать некоторые части, это не так проблематично. Итерация по этому регулярному выражению генерирует имя элемента и его содержимое:

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