如何在字符串中转换Word智能引号和em破折号?

时间:2008-10-06 19:22:34

标签: php unicode smart-quotes

我有一张带有textarea的表单。用户输入存储在数据库中的文本块。

有时用户会粘贴包含智能引号或emdashes的Word文本。这些字符在数据库中显示为: - ,“,”,“

我应该在输入字符串上调用哪些函数将智能引号转换为常规引号,将emdashes转换为常规短划线

我在PHP工作。

更新:感谢迄今为止所有出色的回复。 Joel网站上关于编码的页面非常有用:http://www.joelonsoftware.com/articles/Unicode.html

关于我的环境的一些注意事项:

MySQL数据库使用UTF-8编码。同样,显示内容的HTML页面通过显式设置元内容类型使用UTF-8(Update :)。

在这些页面上,智能引号和emdashes显示为带问号的钻石。

解决方案:

再次感谢您的回复。解决方案有两个方面:

  1. 确保数据库和HTML 文件被明确设置为使用 UTF-8编码。
  2. 使用htmlspecialchars()代替 htmlentities()

13 个答案:

答案 0 :(得分:15)

这听起来像是一个Unicode问题。 Joel Spolsky在这个话题上有一个很好的起点:http://www.joelonsoftware.com/articles/Unicode.html

答案 1 :(得分:9)

  

mysql数据库使用的是UTF-8   编码。同样,html页面   显示内容正在使用   UTF-8。

HTML的内容可以是UTF-8,是的,但你是否明确地将HTML页面的内容类型(编码)(通过PHP生成?)设置为UTF-8?尝试返回Content-Type "text/html;charset=utf-8"标题或向您的HTML添加<meta>标记:

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

这样,提交给PHP的数据的内容类型也将是相同的。

我遇到了类似的问题,并添加了<meta>标签。

答案 2 :(得分:4)

听起来真正的问题是您的数据库没有使用与您的页面相同的字符编码(可能应该是UTF-8)。在这种情况下,如果任何用户提交非ASCII字符,您可能会在数据库中看到奇怪的字符。找到并修复其中的几个(曲线引号和破折号)并不能解决真正的问题。

以下是migrating your database to another character encoding的一些信息,至少对于MySQL数据库而言。

答案 3 :(得分:2)

这是一个不幸的常见问题,但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,则会无声地丢弃无法在目标字符集中表示的字符。

答案 4 :(得分:1)

我们经常会使用标准的字符串替换函数。尽管在该上下文中ASCII / Unicode的性质非常模糊,但它仍然有效。只需确保您的php文件以正确的编码格式保存等。

答案 5 :(得分:1)

根据我的经验,更容易接受智能引号并确保您在任何地方使用相同的编码。首先,将其添加到表单标记中:accept-charset="utf-8"

答案 6 :(得分:1)

您可以尝试从ISO-8859-1到UTF-8的mb_ convert_encoding

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

这假设您需要UTF-8,转换可以找到合理的替换...如果没有,mb_str_replace或preg_replace自己。

答案 7 :(得分:1)

您必须确保您的数据库连接已配置为接受并向客户端提供UTF-8(否则它将转换为“默认”,通常是latin1)。

实际上,这意味着运行查询SET NAMES'utf8';

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

此外,智能引号是windows-1252字符集的一部分,而不是iso-8859-1(latin-1)。与您的问题不太相关,但仅限于FYI。欧元符号也在那里。

答案 8 :(得分:1)

问题出在mysql charset上,我用这行代码解决了我的问题。

mysql_set_charset('utf8',$link); 

答案 9 :(得分:1)

您必须手动将各列的排序规则更改为UTF8;整体更改数据库不会改变这些。

答案 10 :(得分:1)

如果您希望在保留其外观时逃离这些字符,那么您的字符串将显示如下:“这很好!”< / strong>而不是&#34;它很无聊&#34; ......

您可以使用自己的自定义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); 
}

答案 11 :(得分:0)

这可能不是最佳解决方案,但我会尝试测试以找出PHP看到的内容。让我们说它看到“—(还有一些其他的可能性,比如简单的“”或“也许”&amp;#8220;“)。然后做一个str_replace去除所有这些并用普通引号替换它们,然后将答案填入数据库。

更好的解决方案可能是让端到端数据通过所有UTF-8,因为人们正试图在其他答案中提供帮助。

答案 12 :(得分:0)

实际上问题不是在PHP中发生,而是在JavaScript中发生,这是由于从Word复制/粘贴,因此您需要在将文本传递给PHP之前用JavaScript解决问题,请参阅此答案{ {3}}