Проблема с PHP utf8

У меня есть некоторые проблемы, сравнивающие массив с норвежскими символами с символом utf8.

Все символы, за исключением особых норвежских символов (æ, ø, å), отлично работают.

function isNorwegianChar($Char)
{
 $aNorwegianChars = array('a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', 'e', 'E', 'f', 'F', 'g', 'G', 'h', 'H', 'i', 'I', 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N', 'o', 'O', 'p', 'P', 'q', 'Q', 'r', 'R', 's', 'S', 't', 'T', 'u', 'U', 'v', 'V', 'w', 'W', 'x', 'X', 'y', 'Y', 'z', 'Z', 'æ', 'Æ', 'ø', 'Ø', 'å', 'Å', '=', '(', ')', ' ', '-');
 $iArrayLength = count($aNorwegianChars);
 for($iCount = 0; $iCount < $iArrayLength; $iCount++)
 {
 if($aNorwegianChars[$iCount] == $Char)
 {
 return true;
 }
 }
 return false;
}

Если у кого-нибудь есть представление о том, что я могу сделать, прошу сообщить мне.

Update:

Причиной этого является то, что я пытаюсь разобрать текстовый файл, содержащий строки с норвежскими и китайскими словами, например словарь. Я хочу разделить строку на строки, одну из которых содержит норвежское слово, а другое - на китайском. Это позже будет вставлено в базу данных. Пример строк:

impulsiv 形 衝動 的

imøtegå 動 反對, 反駁

imøtekomme 動 符合

alkoholmisbruk (er) 名 濫用 酒精 (名 濫用 酒精 的 人)

alkoholpåvirket 形 受 酒精 影響 的

алкотест 名 呼吸 性 酒精 測試

alkymi (st) 名 煉金術 (名 煉金術 士)

all, alt, alle, 形 全部, 所有

Как вы можете видеть, между словами могут быть пробелы, поэтому я не могу использовать что-то легкое, как взрыв, чтобы разделиться между китайскими и норвежскими словами. Я использую isNorwegianChar и цикл через строку, пока не найду char, который не находится в массиве.

Проблема заключается в том, что он æ, ø и å не возвращается как норвежский персонаж, и он считает, что китайское слово началось.

Вот код:

//Open file.
$rFile = fopen("norsk-kinesisk.txt", "r");
// Loop through the file.
$Count = 0;
while(!feof($rFile))
{
 if(40== $Count)
 {
 break;
 }
 $sLine = fgets($rFile);
 if(0 == $Count)
 {
 $sLine = mb_substr($sLine, 3);
 }
 $iLineLength = strlen($sLine);
 $bChineseHasStarted = false;
 $sNorwegianWord = '';
 $sChineseWord = '';
 for($iCount2 = 0; $iCount2 < $iLineLength; $iCount2++)
 {
 $char = mb_substr($sLine, $iCount2, 1);
 if(($bChineseHasStarted === false) && (false == isNorwegianChar($char)))
 {
 $bChineseHasStarted = true;
 }
 if(false === $bChineseHasStarted)
 {
 $sNorwegianWord .= $char;
 }
 else
 {
 $sChineseWord .= $char;
 }
 //echo $char;
 }
 $sNorwegianWord = trim($sNorwegianWord);
 $sChineseWord = trim($sChineseWord);
 $Count++;
}
fclose($rFile);
7 ответов

Если ваш файл PHP script имеет кодировку ANSI, а не UTF-8, то на байтовом уровне эти норвежские символы будут отличаться от того, что они будут, если бы они были закодированы в UTF-8. Поскольку PHP является языком обработки байтов, а не языком обработки текста, он должным образом сравнивает байтовые последовательности и делает вывод, что они не совпадают.

Чтобы решить эту проблему, вы можете убедиться, что ваш PHP script имеет ту же кодировку, что и набор символов, с которым вы сравниваете, или вы можете использовать библиотеки iconv или mbstring для преобразования в соответствующие наборы символов.

Кроме того, если вы его не прочитали, прочитайте следующее: http://www.joelonsoftware.com/articles/Unicode.html

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


Прежде всего, и я получу UTF-8 позже, если никто не ответит, итерация, подобная вам, является очень плохим способом поиска по массиву. PHP имеет встроенные функции только для этого:

http://fr.php.net/array_search

Итак, вы можете попробовать попробовать и посмотреть, помогает ли ваша проблема. Также убедитесь, что файл PHP, который вы пишете, также закодирован в UTF-8!

UPDATE:

Попробуйте использовать следующий код, который отлично работает на моем сервере. Если он не работает, проверьте, что PHP настроен на работу с UTF-8 по умолчанию или добавление необходимых вызовов ini_set.

<title>norvegian utf-8 test</title>

<!--?php
function isSpecial($char) {
 $special_chars = array("æ", "ø", "å", "か");
 return (array_search($char, $special_chars) !== false);
}
if (isset($_REQUEST["char"])) {
 echo $_REQUEST["char"].(isSpecial($_REQUEST["char"])?" (true)":" (false)");
}
?-->


Я, наконец, понял это. Возможно, это не лучший способ сделать это, но он работает.

Кажется, что массив, с которым я работал, находился в другой кодировке, чем входной символ. Я решил это, создав строку из всех элементов массива, а затем применил mb_strpos для поиска символов. Таким образом, единственным изменением кода является функция isNorwegianChar. Новая функция выглядит следующим образом:

function isNorwegianChar($Char)
{
 $sNorwegianChars = "'aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZæÆøØåÅ=() -,";
 if(mb_strpos($sNorwegianChars, $Char))
 {
 return true;
 }
 else
 {
 return false;
 }
}

Спасибо за помощь!


Попробуйте использовать функции для кодирования и декодирования utf8. может помочь


Из того, что я знаю, лучше всего установить расширение mbstring (http://www.php.net/manual/en/ref.mbstring.php), если у вас есть доступ к веб-серверу.


Поскольку проблема состоит в том, чтобы отделить норвежское слово (слова) от китайских, почему бы вам не использовать явный глиф для этого (я лично, как "¶" ), вместо того, чтобы полагаться на алгоритм?

impulsiv¶ 形 衝動 的

Затем используйте mb-split или mb-substr в сочетании с mb-strpos.

Вы можете легко заменить его пространством, если вам нужно вывести строку!

К сожалению, PCRE в PHP не позволяет нам использовать \p с script имена.

(найдите "InMusicalSymbols" в regexp.reference, в § "Свойства символа Юникода", чтобы понять, что я имею в виду)


Посмотрите, установлено ли расширение расширения mbstring

licensed under cc by-sa 3.0 with attribution.