Как преобразовать умные кавычки Word и их тире в строку? - PullRequest
25 голосов
/ 06 октября 2008

У меня есть форма с текстовой областью. Пользователи вводят блок текста, который хранится в базе данных.

Иногда пользователь вставляет текст из Word, содержащий умные кавычки или вставки. Эти символы появляются в базе данных как:,, 1003 *

Какую функцию следует вызывать во входной строке для , чтобы преобразовать умные кавычки в обычные кавычки, а электронные черты - в обычные тире ?

Я работаю в PHP.

Обновление: спасибо за все замечательные ответы до сих пор. Страница на сайте Джоэла о кодировках очень информативна: http://www.joelonsoftware.com/articles/Unicode.html

Некоторые примечания по моей среде:

База данных MySQL использует кодировку UTF-8. Аналогично, HTML-страницы, которые отображают контент, используют UTF-8 (Update :), явно указав мета-тип контента.

На этих страницах умные кавычки и пометки отображаются в виде ромба с вопросительным знаком.

Решение:

Еще раз спасибо за ответы. Решение было двояким:

  1. Убедитесь, что база данных и HTML файлы были явно установлены для использования Кодировка UTF-8.
  2. Используйте htmlspecialchars() вместо htmlentities().

Ответы [ 13 ]

15 голосов
/ 06 октября 2008

Это звучит как проблема Unicode. У Джоэла Спольски есть хорошая отправная точка по теме: http://www.joelonsoftware.com/articles/Unicode.html

9 голосов
/ 07 октября 2008

База данных mysql использует UTF-8 кодирование. Аналогично, HTML-страницы которые отображают контент используют UTF-8.

Содержимое HTML может быть в UTF-8, да, но вы явно устанавливаете тип содержимого (кодирование) ваших HTML-страниц (сгенерированных с помощью PHP?) Также в UTF-8? Попробуйте вернуть Content-Type заголовок "text/html;charset=utf-8" или добавить <meta> теги к своим HTML:

<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>

Таким образом, тип содержимого данных, передаваемых в PHP, также будет таким же.

У меня была похожая проблема, и добавление тега <meta> мне помогло.

4 голосов
/ 06 октября 2008

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

Вот некоторая информация о миграции вашей базы данных в другую кодировку символов , по крайней мере, для базы данных MySQL.

2 голосов
/ 06 октября 2008

Это, к сожалению, слишком распространенная проблема, которой не помогает очень плохая обработка наборов символов в PHP.

То, что мы делаем, это форсируем текст через iconv

// Convert input data to UTF8, ignore any odd (MS Word..) chars
// that don't translate
$input = iconv("ISO-8859-1","UTF-8//IGNORE",$input);

Флаг //IGNORE означает, что все, что не может быть переведено, будет выброшено.

Если вы добавите строку // IGNORE, символы, которые не могут быть представлены в целевой кодировке, будут отброшены.

1 голос
/ 16 октября 2014

Если вы искали экранирование этих символов для Интернета, сохраняя их внешний вид, поэтому ваши строки будут выглядеть следующим образом: «Это хорошо!» а не "Это скучно" ...

Вы можете сделать это, используя собственную пользовательскую функцию htmlEncode вместо PHP htmlentities () :

$trans_tbl = false;

function htmlEncode($text) {

  global $trans_tbl;

  // create translation table once
  if(!$trans_tbl) {
    // start with the default set of conversions and add more.

    $trans_tbl = get_html_translation_table(HTML_ENTITIES); 

    $trans_tbl[chr(130)] = '&sbquo;';    // Single Low-9 Quotation Mark
    $trans_tbl[chr(131)] = '&fnof;';    // Latin Small Letter F With Hook
    $trans_tbl[chr(132)] = '&bdquo;';    // Double Low-9 Quotation Mark
    $trans_tbl[chr(133)] = '&hellip;';    // Horizontal Ellipsis
    $trans_tbl[chr(134)] = '&dagger;';    // Dagger
    $trans_tbl[chr(135)] = '&Dagger;';    // Double Dagger
    $trans_tbl[chr(136)] = '&circ;';    // Modifier Letter Circumflex Accent
    $trans_tbl[chr(137)] = '&permil;';    // Per Mille Sign
    $trans_tbl[chr(138)] = '&Scaron;';    // Latin Capital Letter S With Caron
    $trans_tbl[chr(139)] = '&lsaquo;';    // Single Left-Pointing Angle Quotation Mark
    $trans_tbl[chr(140)] = '&OElig;';    // Latin Capital Ligature OE

    // smart single/ double quotes (from MS)
    $trans_tbl[chr(145)] = '&lsquo;'; 
    $trans_tbl[chr(146)] = '&rsquo;'; 
    $trans_tbl[chr(147)] = '&ldquo;'; 
    $trans_tbl[chr(148)] = '&rdquo;'; 

    $trans_tbl[chr(149)] = '&bull;';    // Bullet
    $trans_tbl[chr(150)] = '&ndash;';    // En Dash
    $trans_tbl[chr(151)] = '&mdash;';    // Em Dash
    $trans_tbl[chr(152)] = '&tilde;';    // Small Tilde
    $trans_tbl[chr(153)] = '&trade;';    // Trade Mark Sign
    $trans_tbl[chr(154)] = '&scaron;';    // Latin Small Letter S With Caron
    $trans_tbl[chr(155)] = '&rsaquo;';    // Single Right-Pointing Angle Quotation Mark
    $trans_tbl[chr(156)] = '&oelig;';    // Latin Small Ligature OE
    $trans_tbl[chr(159)] = '&Yuml;';    // Latin Capital Letter Y With Diaeresis

    ksort($trans_tbl);
  }

  // escape HTML      
  return strtr($text, $trans_tbl); 
}
1 голос
/ 10 октября 2011

Необходимо вручную изменить параметры сортировки отдельных столбцов на UTF8; изменение базы данных в целом не изменит их.

1 голос
/ 24 октября 2010

проблема в кодировке mysql, я исправил проблемы с этой строкой кода.

mysql_set_charset('utf8',$link); 
1 голос
/ 07 октября 2008

Вы должны быть уверены, что ваше соединение с базой данных настроено на прием и передачу UTF-8 от клиента и к клиенту (в противном случае оно преобразуется в значение «по умолчанию», обычно латинское 1).

На практике это означает выполнение запроса SET NAMES 'utf8';

http://www.phpwact.org/php/i18n/utf-8/mysql

Кроме того, умные кавычки являются частью набора символов windows-1252, а не iso-8859-1 (latin-1). Не очень актуально для вашей проблемы, но только к вашему сведению. Там же находится символ евро.

1 голос
/ 06 октября 2008

Вы можете попробовать mb_ convert_encoding из ISO-8859-1 в UTF-8.

$str = mb_convert_encoding($str, 'UTF-8', 'ISO-8859-1');

Предполагается, что вы хотите использовать UTF-8, и преобразование может найти разумные замены ... в противном случае mb_str_replace или preg_replace их сами.

1 голос
/ 06 октября 2008

По моему опыту, проще просто принять умные цитаты и убедиться, что везде используется одна и та же кодировка. Для начала добавьте это в свой тег формы: accept-charset="utf-8"

...