【问题标题】:Two question marks in diamonds instead of upsidedown exclamation mark菱形中的两个问号而不是倒置的感叹号
【发布时间】:2012-12-07 06:59:30
【问题描述】:

我在 Mac OS X 10 上使用 eclipse-php 在 php 中处理一些带有西班牙语文本的文本文件。我将编码设置为 UTF-8,除了一个小问题外,一切都很好。在输出文本文件中,所有¡(倒置感叹号)都替换为� �(两个黑色菱形,问号用空格隔开)。其他角色 (¿ñáéíóúü) 都没有给我带来任何麻烦。我的 Windows Vista 机器也有类似的问题(它会将所有 ¡ 替换为 é)。任何想法为什么这个字符在 UTF-8 中出现问题以及我如何修复它?

这是我正在使用的代码。我最初没有包括它,因为它太长了,我不确定问题出在哪里。如您所见,我已尝试采纳shiplu.mokadd.im 的建议,但我仍然收到� �

<?php

ini_set("auto_detect_line_endings", true);

$sourceH = fopen("MainInput.txt", "r") or die("Can't open MainInput.txt.");
$sourceData = array();
$tracker = 0;

while (!feof($sourceH)){
    $sourceData[$tracker] = fgets($sourceH);
    $sourceData[$tracker] = preg_split("/\t/", $sourceData[$tracker]);
    $tracker++;
}

$i = $tracker--;

$chars_hi = 'ABCDEFGHIJKLMNÑOPQRSTUVWXYZÁÉÍÓÚÜ';
$chars_lo = 'abcdefghijklmnñopqrstuvwxyzáéíóúü';
$characters = "ABCDEFGHIJKLMNÑOPQRSTUVWXYZÁÉÍÓÚÜabcdefghijklmnñopqrstuvwxyzáéíóúü1234567890'-";

function lowercase($s) {
    global $chars_hi, $chars_lo;
    return strtr($s, $chars_hi, $chars_lo);
}

$myNewFile = "Processing/Prepared.txt";
$fhNew = fopen($myNewFile, 'w') or die("can't open Prepared\n");
$newText = "";

for ($n = 1; $n < $i; $n++) {

    $myFile = $sourceData[$n][1];
    $fh = fopen($myFile,'r') or die("can't open file ".$sourceData[$n][1]."\n");
    fwrite($fhNew, "\n\nStartFile ".$sourceData[$n][0]."\n\n");
    $position = 0;
    $speaker = ">>u";

    while (!feof($fh)){
        $newText = fgets($fh);
        $isLast = false;
        $isFirst = true;
        $new = "";
        if (mb_strpos($newText, ">> i") !== false or mb_strpos($newText, ">>i") !== false or mb_strpos($newText, ">i") !== false or mb_strpos($newText, "> i") !== false) {
            $speaker = ">>i";
        }
        elseif (mb_strpos($newText, ">> s") !== false or mb_strpos($newText, ">>s") !== false or mb_strpos($newText, ">s") !== false or mb_strpos($newText, "> s") !== false) {
            $speaker = ">>s";
        }
        for ($in = 0; $in < mb_strlen($newText); $in++) {
            if (mb_strpos($characters, $newText[$in]) !== false) {
                if ($isFirst == true) {
                    $new = $new." ".$newText[$in];
                    $isFirst = false;
                    $isLast = true;
                }
                else {
                    $new = $new.$newText[$in];
                }
            }
            elseif ($isLast == true) {
                $isLast = false;
                $isFirst = true;
                $new = $new."   ".($in + $position)."   ".$speaker."    ".$newText[$in];
            }
            else {
                $new = $new.$newText[$in];
            }
        }
        $position += mb_strlen($newText);
        $newText = $new;
        $newText = lowercase($newText);
        fwrite($fhNew, $newText."\n");
    }
    fclose($fh);
}
fclose($fhNew);

?>

【问题讨论】:

    标签: php eclipse unicode utf-8 character-encoding


    【解决方案1】:

    你不能这样做:

    $new = $new." ".$newText[$in];
    

    具体来说,$newText[$in]。这确实是字节级访问,但是在使用 UTF-8 时,字符由多个字节组成。因此,当您像这样 hack 和 slash 字节时,您会将属于一起的 UTF-8 字节分开,从而产生

    例如,运行这个 PHP 脚本(在文本编辑器中保存为 UTF-8):

    <?php
    header("Content-Type: text/html; charset=UTF-8");
    $text = "ä";
    echo $text[0] . " " . $text[1];
    

    结果是� �

    您必须修复您正在对字符串进行[] 访问的所有代码。您可以将$string[$i] 替换为mb_substr( $string, $i, 1, "UTF-8" );

    另外,您是否将mb_internal_encoding 设置为"UTF-8"?否则,当您在没有显式编码的情况下调用 mb_* 函数时,它很可能不会默认为 UTF-8。

    我还建议在您的自定义 lowercase 函数上使用 mb_convert_case($str, MB_CASE_LOWER, "UTF-8"); 之类的东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-12
      • 2022-07-26
      • 1970-01-01
      • 1970-01-01
      • 2011-12-22
      • 2018-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多