Проблема 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;

}

Если у кого-то есть идеи о том, что я могу сделать, пожалуйста, дайте мне знать.

Обновлять:

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

impulsiv 形 衝動 的

imøtegå 動 反對 , 反駁

imøtekomme 動 符合

alkoholmisbruk (эр) 名 濫用 酒精 (名 濫用 酒精 的 人)

alkoholpåvirket 形 受 酒精 影響 的

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

алкимы (ул) 名 煉金術 (名 煉金術 士)

все, альт, все, 形 全部,

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

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

Вот код:

   //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);

Версия PHP - 5.2.5.

Christoffer 03.10.2008 16:56

Вы можете использовать range () как сокращение при построении массива.

Ted Percival 03.10.2008 17:17

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

Gilles 03.10.2008 19:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
3
3
6 587
7

Ответы 7

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

http://fr.php.net/array_search

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

Обновлено:

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

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head><title>norvegian utf-8 test</title>
<meta http-equiv = "Content-type" value = "text/html; charset=UTF-8" />
</head>

<body>

<?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)");
}


?>

<form  method = "POST" accept-charset = "UTF-8">
<input type = "text" name = "char">
<input type = "submit" value = "submit">
</form>


</body>
</html>

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

Christoffer 03.10.2008 16:49

@Chistoffer Я напишу тестовый файл и опробую его на своем сервере. Я широко использую UTF-8, поэтому знаю, что у меня все правильно настроено с точки зрения UTF-8.

Gilles 03.10.2008 17:04

Спасибо! Ваш пример отлично работает на моем компьютере. Ошибка должна быть где-то еще. Я дополню вопрос дополнительной информацией.

Christoffer 03.10.2008 17:40

@Gilles ... Я не видел! == false в ответах подобным образом. Не могли бы вы объяснить это, пожалуйста? Также вам не нужно использовать круглые скобки вокруг ваших возвращаемых аргументов. Поскольку return - это скобка языковой конструкции, обработка фактически замедляется.

rg88 03.10.2008 18:00

@ gaoshan88 из статьи php.net о array_search: эта функция может возвращать логическое значение FALSE, но также может возвращать не-логическое значение, которое оценивается как FALSE, например 0 или "". Пожалуйста, прочтите раздел о логических значениях для получения дополнительной информации. Используйте оператор === для проверки возвращаемого значения этой функции.

Gilles 03.10.2008 19:13

и, очевидно, злой близнец === -! ==

Gilles 03.10.2008 19:13

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

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

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

Также, если вы не читали, прочтите это: http://www.joelonsoftware.com/articles/Unicode.html

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

Спасибо за ответ. Мой PHP-скрипт сохраняется как UTF-8, mbstring говорит, что входной char - UTF-8, но значения массива - ASCII.

Christoffer 03.10.2008 16:58

ASCII не поддерживает норвежские символы, я предполагаю, что вы имеете в виду ANSI latin1. В вашем случае я бы просто вывел символы, которые вы пытаетесь сравнить, и посмотрел бы на их байтовые значения.

Joeri Sebrechts 03.10.2008 17:55

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

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

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

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

function isNorwegianChar($Char)
{
    $sNorwegianChars = "'aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZæÆøØåÅ=() -,";

    if (mb_strpos($sNorwegianChars, $Char))
    {
        return true;
    }
    else
    {
        return false;
    }
}

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

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

impulsiv 形 衝動 的

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

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

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

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

Спасибо за предложение! Причина, по которой не используется символ и не разбивается строка на этот символ, заключается в том, что файл, содержащий строку, содержит 22 000 строк. И я не хочу редактировать 22k строк вручную.

Christoffer 06.10.2008 12:20

Другие вопросы по теме