钻石中的两个问号而不是倒置的感叹号

Laa*_*vin 2 php eclipse unicode utf-8 character-encoding

我在Mac OS X 10上使用eclipse-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);

?>
Run Code Online (Sandbox Code Playgroud)

Esa*_*ija 5

你做不到这样的事情:

$new = $new." ".$newText[$in];
Run Code Online (Sandbox Code Playgroud)

具体来说,$newText[$in].这可以进行字节级访问,但使用UTF-8时,字符由多个字节组成.因此,当您破解并删除这样的字节时,您将分离属于一起的UTF-8字节,从而产生?.

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

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

结果是? ?.

您必须修复您[]在字符串上访问的所有代码.您可以替换$string[$i]使用mb_substr( $string, $i, 1, "UTF-8" );

此外,你设置mb_internal_encoding"UTF-8"?否则,在mb_*没有显式编码的情况下调用函数时,很可能不会默认为UTF-8 .

我还建议使用类似于mb_convert_case($str, MB_CASE_LOWER, "UTF-8");自定义lowercase功能的东西.