Как мне лучше всего удалить символы юникода, которые XHTML считает недействительными при использовании php? - PullRequest
7 голосов
/ 13 апреля 2010

Я управляю форумом, предназначенным для поддержки международной математической группы. Я недавно переключил его на Unicode для лучшей поддержки международных символов. При отладке этого преобразования я обнаружил, что не все символы Юникода считаются действительными XHTML (соответствующий веб-сайт выглядит как http://www.w3.org/TR/unicode-xml/).. Один из шагов, который проходит программное обеспечение форума перед представлением сообщений в браузере, заключается в следующем: этап проверки / дезинфекции XHTML. Представляется разумным предположение, что на этом этапе следует удалить все символы Юникода, которые не нравятся XHTML.

Итак, мой вопрос:

Существует ли стандартный (или лучший) способ сделать это в PHP?

(Кстати, форум написан на PHP.)

Полагаю, что отказоустойчивость была бы простой str_replace (если это тоже самое лучшее, нужно ли мне что-то делать дополнительно, чтобы убедиться, что оно работает правильно с юникодом?), Но это потребует от меня прохождения XHTML DTD (или упомянутая выше страница W3) тщательно выяснить, какие символы перечислить в search части str_replace, так что, если это лучший способ, кто-то уже сделал это, чтобы я мог украсть, ошибаться, скопировать, это?

(Между прочим, символ, вызвавший проблему, был U + 000C, 'formfeed', который (согласно странице W3) является допустимым HTML, но недопустимым XHTML!)

Ответы [ 2 ]

2 голосов
/ 13 апреля 2010

Я нашел функцию, которая может делать то, что вы хотите на phpedit.net .

Выложу функцию для архива, кредиты на ltp на PHPEdit.net:

/**
 * Removes invalid XML
 *
 * @access public
 * @param string $value
 * @return string
 */
function stripInvalidXml($value)
{
    $ret = "";
    $current;
    if (empty($value)) 
    {
        return $ret;
    }

    $length = strlen($value);
    for ($i=0; $i < $length; $i++)
    {
        $current = ord($value{$i});
        if (($current == 0x9) ||
            ($current == 0xA) ||
            ($current == 0xD) ||
            (($current >= 0x20) && ($current <= 0xD7FF)) ||
            (($current >= 0xE000) && ($current <= 0xFFFD)) ||
            (($current >= 0x10000) && ($current <= 0x10FFFF)))
        {
            $ret .= chr($current);
        }
        else
        {
            $ret .= " ";
        }
    }
    return $ret;
}
1 голос
/ 13 апреля 2010

Предполагая, что вы вводите utf8, вы можете удалить диапазоны Unicode с помощью чего-то вроде

 preg_replace('~[\x{17A3}-\x{17D3}]~u', '', $input);

Другой, более лучший, подход состоит в том, чтобы удалить все по умолчанию и только те символы белого списка, которые вы хотите видеть. Свойства Unicode (\ p) вполне практичны для этого. Например, удаляет все, кроме (Unicode) букв и цифр:

  preg_replace('~[^\p{L}\p{N}]~u', '', $input)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...