Усеченный текст, содержащий HTML, игнорируя теги

uname

или

uname -a

, если Вы хотите больше информации

36
задан trejder 6 March 2015 в 15:22
поделиться

5 ответов

Предполагая, что вы используете допустимый XHTML, легко проанализировать HTML и убедиться, что теги обрабатываются правильно. Вам просто нужно отследить, какие теги были открыты до сих пор, и обязательно закрыть их снова «на выходе».

<?php
header('Content-type: text/plain; charset=utf-8');

function printTruncated($maxLength, $html, $isUtf8=true)
{
    $printedLength = 0;
    $position = 0;
    $tags = array();

    // For UTF-8, we need to count multibyte sequences as one character.
    $re = $isUtf8
        ? '{</?([a-z]+)[^>]*>|&#?[a-zA-Z0-9]+;|[\x80-\xFF][\x80-\xBF]*}'
        : '{</?([a-z]+)[^>]*>|&#?[a-zA-Z0-9]+;}';

    while ($printedLength < $maxLength && preg_match($re, $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 ($printedLength >= $maxLength) break;

        if ($tag[0] == '&' || ord($tag) >= 0x80)
        {
            // Pass the entity or UTF-8 multibyte sequence through unchanged.
            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(10, '<b>&lt;Hello&gt;</b> <img src="world.png" alt="" /> world!'); print("\n");

printTruncated(10, '<table><tr><td>Heck, </td><td>throw</td></tr><tr><td>in a</td><td>table</td></tr></table>'); print("\n");

printTruncated(10, "<em><b>Hello</b>&#20;w\xC3\xB8rld!</em>"); print("\n");

Примечание по кодировке : В приведенном выше коде предполагается, что XHTML - это UTF-8 закодировано. ASCII-совместимые однобайтовые кодировки (такие как Latin-1 ) также поддерживаются, просто передайте false в качестве третьего аргумента. Другие многобайтовые кодировки не поддерживаются, хотя вы можете взломать поддержку, используя mb_convert_encoding для преобразования в UTF-8 перед вызовом функции, а затем снова преобразовать обратно в каждом операторе print .

(Вы должны всегда использовать UTF-8.)

Изменить : Обновлено для обработки символьных сущностей и UTF-8. Исправлена ​​ошибка, из-за которой функция печатала на один символ слишком много, если этот символ был символьной сущностью.

47
ответ дан 27 November 2019 в 05:42
поделиться

Если контекст вашего кода имеет доступ в Интернет, вы можете попробовать использовать Google API для определения языка. http://code.google.com/apis/ajaxlanguage/documentation/

var text = "¿Dónde está el baño?";
google.language.detect(text, function(result) {
  if (!result.error) {
    var language = 'unknown';
    for (l in google.language.Languages) {
      if (google.language.Languages[l] == result.language) {
        language = l;
        break;
      }
    }
    var container = document.getElementById("detection");
    container.innerHTML = text + " is: " + language + "";
  }
});

И, поскольку вы используете C #, ознакомьтесь с этой статьей о том, как вызывать API из C #. .

ОБНОВЛЕНИЕ: ] + $ в конце, чтобы избавиться от возможно поврежденного объекта)

  • Исправьте это с помощью HTML Tidy
  • 4
    ответ дан 27 November 2019 в 05:42
    поделиться

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

    $dom = new DOMDocument();
    $dom->loadHTML(substr("Hello, my <strong>name</strong> is <em>Sam</em>. I&acute;m a web developer.",0,26));
    $html = preg_replace("/\<\/?(body|html|p)>/", "", $dom->saveHTML());
    echo $html;
    

    Should вывести: Здравствуйте, мое ** имя ** .

    2
    ответ дан 27 November 2019 в 05:42
    поделиться

    Это очень сложно сделать без использования валидатора и синтаксического анализатора, причина в том, что представьте, если у вас есть

    <div id='x'>
        <div id='y'>
            <h1>Heading</h1>
            500 
            lines 
            of 
            html
            ...
            etc
            ...
        </div>
    </div>
    

    Как вы планируете обрезать это и в итоге получить действительный HTML?

    После краткого поиска я нашел эту ссылку , которая могла помочь.

    0
    ответ дан 27 November 2019 в 05:42
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: