2012-12-19 6 views
2

Mac OS X 10에서 PHP로 스페인어 텍스트가있는 일부 텍스트 파일을 처리하고 있습니다. 인코딩이 UTF-8로 설정되어 있고 모든 것이 훌륭하게 작동합니다. 하나의 작은 문제를 제외하고. ¡ (거꾸로 된 느낌표)은 모두 출력 텍스트 파일에 � � (물음표가 공백으로 구분 된 두 개의 검은 색 다이아몬드)으로 바뀝니다. 다른 문자 (¿ñáéíóúü)는 아무런 문제가 없습니다. 내 Windows Vista 컴퓨터에서 이와 유사한 문제가 발생했습니다 (모두 ¡é으로 바꿉니다). 이 한 문자가 UTF-8로 도청당하는 이유와 해결 방법은 무엇입니까?다이아몬드의 두 물음표가 upsidedown 느낌표 대신

다음은 내가 사용하고있는 코드입니다. 원래 너무 길기 때문에 문제가있는 곳을 잘 모릅니다. 보시다시피 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); 

?> 
+2

코드를 표시해야합니다. – Esailija

답변

5

당신은 이런 식으로 물건을 수행 할 수 없습니다

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

특히, $newText[$in]. 바이트 단위 액세스를 수행하지만 UTF-8을 사용하면 문자는 여러 바이트로 구성됩니다. 따라서 이와 같이 바이트를 해킹하고 슬래시하면 함께 소속 된 UTF-8 바이트가 분리되어 이됩니다.

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

결과는 � �입니다 :

예를 들어, (UTF-8로 텍스트 편집기에 저장)이 PHP 스크립트를 실행합니다.

문자열에서 [] 액세스를 수행하는 모든 코드를 수정해야합니다. $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");과 같은 것을 사용하는 것이 좋습니다.

+0

대단합니다, 잘 작동합니다! 대단히 감사합니다 !! – Laaevin

관련 문제