Определить язык из строки в PHP

29
задан Swiss Mister 14 March 2014 в 11:33
поделиться

15 ответов

Вы не можете определить язык по типу символа. И нет надежных способов сделать это.

С любым методом вы просто делаете обоснованное предположение. Есть некоторые математические статьи там

17
ответ дан Ólafur Waage 14 March 2014 в 11:33
поделиться

Вы можете реализовать модуль Apache Tika с Java, вставить результаты в текстовый файл, БД и т. Д., А затем прочитать из файла db, что угодно с помощью php. Если у вас не так много контента, вы можете использовать API Google, хотя имейте в виду, что ваши звонки будут ограничены, и вы можете отправлять только ограниченное количество символов в API. На момент написания статьи я закончил тестирование API-версии 1 (которая оказалась не очень точной) и версии 2 лабораторных работ (я отказался от чтения, прочитав, что в день существует ограничение в 100 000 символов).

0
ответ дан Osvaldo Mercado 14 March 2014 в 11:33
поделиться

У меня были хорошие результаты с https://github.com/patrickschur/language-detection , и я использую его в производстве:

  • Он использует нграммы в языках для определить наиболее вероятный язык (чем длиннее ваша строка / чем больше слов, тем точнее он будет), что кажется надежным проверенным методом.
  • Поддерживается 110 языков, но вы также можете ограничить количество языков только теми, кто вас интересует.
  • Обучающий и языковой детектор можно легко улучшить / настроить. Он использует Всеобщую декларацию прав человека на каждом из языков в качестве основы для определения языка, но если вы знаете, с какими типами предложений вы сталкиваетесь, вы можете легко расширить или заменить используемые тексты на каждом языке и быстро получить лучшие результаты. «Тренировать» эту библиотеку, чтобы стать лучше, легко.
  • Я бы предложил увеличить setMaxNgrams (я установил его на 9000) в Трейнере и запустить его один раз, а затем также использовать эту настройку в классе детектора языка. Изменение числа ngrams немного неинтуитивно (мне пришлось просмотреть код, чтобы выяснить, как он работает), что является недостатком, и по умолчанию (310), на мой взгляд, всегда слишком мало. Больше нграмм делает гадание намного лучше.
  • Поскольку библиотека очень мала, было относительно легко понять, что происходит и как ее настроить.

Мое использование: я анализирую электронные письма для системы CRM, чтобы узнать, на каком языке написано электронное письмо, поэтому отправка текста в стороннюю службу не была возможной. Несмотря на то, что Всеобщая декларация прав человека, вероятно, не является лучшей основой для классификации языка электронных писем (поскольку электронные письма часто имеют формальные части, такие как приветствия, которые не являются частью Декларации прав человека), она определяет правильный язык примерно в 99% случаи, если в нем хотя бы 5 слов.

Обновление : мне удалось улучшить распознавание языка в электронных письмах до 100% при использовании библиотеки определения языка следующими способами:

  • Добавить дополнительные общие фразы к (соответствующие) образцы языка, такие как «Привет», «С наилучшими пожеланиями», «С уважением». Подобные выражения не используются во Всеобщей декларации прав человека. Часто используемые фразы помогают распознавать язык, особенно формульные, которые часто используют мои люди («Привет», «Хорошего дня»), если вы анализируете человеческое общение.
  • Установите максимальную длину ngram на 4 (вместо значения по умолчанию 3).
  • Держите maxNgrams на 9000, как и раньше.

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

1
ответ дан iquito 14 March 2014 в 11:33
поделиться

Я брал документы на разных языках и сравнивал их с Unicode. Затем вы можете использовать некоторые байесовские рассуждения, чтобы определить, какой это язык, используя только символы Юникода. Это отделило бы французский от английского или русского.

Я не уверен точно, что еще можно сделать, кроме поиска слов в языковых словарях для определения языка (используя аналогичный вероятностный подход).

1
ответ дан MathGladiator 14 March 2014 в 11:33
поделиться

попробуй использовать ascii encode. я использую этот код для определения языков в моем проекте социального бота

function language($string) {
        $ru = array("208","209","208176","208177","208178","208179","208180","208181","209145","208182","208183","208184","208185","208186","208187","208188","208189","208190","208191","209128","209129","209130","209131","209132","209133","209134","209135","209136","209137","209138","209139","209140","209141","209142","209143");
        $en = array("97","98","99","100","101","102","103","104","105","106","107","108","109","110","111","112","113","114","115","116","117","118","119","120","121","122");
        $htmlcharacters = array("<", ">", "&amp;", "&lt;", "&gt;", "&");
        $string = str_replace($htmlcharacters, "", $string);
        //Strip out the slashes
        $string = stripslashes($string);
        $badthings = array("=", "#", "~", "!", "?", ".", ",", "<", ">", "/", ";", ":", '"', "'", "[", "]", "{", "}", "@", "$", "%", "^", "&", "*", "(", ")", "-", "_", "+", "|", "`");
        $string = str_replace($badthings, "", $string);
        $string = mb_strtolower($string);
        $msgarray = explode(" ", $string);
        $words = count($msgarray);
        $letters = str_split($msgarray[0]);
        $letters = ToAscii($letters[0]);
        $brackets = array("[",",","]");
        $letters = str_replace($brackets,  "", $letters);
        if (in_array($letters, $ru)) {
            $result = 'Русский' ; //russian
        } elseif (in_array($letters, $en)) {
            $result = 'Английский'; //english
        } else {
            $result = 'ошибка' . $letters; //error
        }} return $result;  
1
ответ дан Master-Bunny 14 March 2014 в 11:33
поделиться

Возможно, отправьте строку для этого языка:

http://www.xrce.xerox.com/competencies/content-analysis/tools/guesser

1
ответ дан Andy 14 March 2014 в 11:33
поделиться

Одним из подходов может быть разбиение входной строки на слова, а затем поиск этих слов в английском словаре, чтобы увидеть, сколько из них присутствует. Этот подход имеет несколько ограничений:

  • собственные существительные могут плохо обрабатываться
  • орфографические ошибки могут помешать вашему поиску
  • аббревиатуры, такие как «lol» или «b4» не обязательно будет в словаре
1
ответ дан Greg Hewgill 14 March 2014 в 11:33
поделиться

Пакет Text_LanguageDetect груши дал ужасные результаты: «роскошные апартаменты в центре города» были определены как португальский ...

Google API по-прежнему является лучшим решением, они дают бесплатный кредит в размере 300 долларов и предупреждают, прежде чем взимать с вас плату.

Ниже приведена супер простая функция, которая использует file_get_contents для загрузки языка, обнаруженного API, поэтому нет необходимости загружать или устанавливать библиотеки и т. д.

function guess_lang($str) {

    $str = str_replace(" ", "%20", $str);

    $content = file_get_contents("https://translation.googleapis.com/language/translate/v2/detect?key=YOUR_API_KEY&q=".$str);

    $lang = (json_decode($content, true));

    if(isset($lang))
        return $lang["data"]["detections"][0][0]["language"];
 }

Выполнить:

echo guess_lang("luxury apartments downtown montreal"); // returns "en"

Ключ API Google Translate можно получить здесь: https://console.cloud.google.com/apis/library/translate.googleapis. com /

Это простой пример коротких фраз, чтобы помочь вам. Для более сложных приложений вы захотите ограничить свой ключ API и явно использовать библиотеку.

2
ответ дан Robert Sinclair 14 March 2014 в 11:33
поделиться

Я попробовал библиотеку Text_LanguageDetect, и полученные результаты были не очень хорошими (например, текст «тест» был идентифицирован как эстонский, а не английский).

Я могу порекомендовать вам попробовать Яндекс Перевод API , который является БЕСПЛАТНЫМ для 1 миллиона символов на 24 часа и до 10 миллионов символов в месяц. Он поддерживает (согласно документации) более 60 языков.

<?php
function identifyLanguage($text)
{
    $baseUrl = "https://translate.yandex.net/api/v1.5/tr.json/detect?key=YOUR_API_KEY";
    $url = $baseUrl . "&text=" . urlencode($text);

    $ch = curl_init($url);

    curl_setopt($ch, CURLOPT_CAINFO, YOUR_CERT_PEM_FILE_LOCATION);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

    $output = curl_exec($ch);
    if ($output)
    {
        $outputJson = json_decode($output);
        if ($outputJson->code == 200)
        {
            if (strlen($outputJson->lang) > 0)
            {
                return $outputJson->lang;
            }
        }
    }

    return "unknown";
}

function translateText($text, $targetLang)
{
    $baseUrl = "https://translate.yandex.net/api/v1.5/tr.json/translate?key=YOUR_API_KEY";
    $url = $baseUrl . "&text=" . urlencode($text) . "&lang=" . urlencode($targetLang);

    $ch = curl_init($url);

    curl_setopt($ch, CURLOPT_CAINFO, YOUR_CERT_PEM_FILE_LOCATION);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

    $output = curl_exec($ch);
    if ($output)
    {
        $outputJson = json_decode($output);
        if ($outputJson->code == 200)
        {
            if (count($outputJson->text) > 0 && strlen($outputJson->text[0]) > 0)
            {
                return $outputJson->text[0];
            }
        }
    }

    return $text;
}

header("content-type: text/html; charset=UTF-8");

echo identifyLanguage("エクスペリエンス");
echo "<br>";
echo translateText("エクスペリエンス", "en");
echo "<br>";
echo translateText("エクスペリエンス", "es");
echo "<br>";
echo translateText("エクスペリエンス", "zh");
echo "<br>";
echo translateText("エクスペリエンス", "he");
echo "<br>";
echo translateText("エクスペリエンス", "ja");
echo "<br>";
?>
4
ответ дан Muzikant 14 March 2014 в 11:33
поделиться

Я использовал пакет Text_LanguageDetect pear с некоторыми разумными результатами. Он очень прост в использовании и имеет скромную 52-языковую базу данных. Недостатком является отсутствие определения восточноазиатских языков.

require_once 'Text/LanguageDetect.php';
$l = new Text_LanguageDetect();
$result = $l->detect($text, 4);
if (PEAR::isError($result)) {
    echo $result->getMessage();
} else {
    print_r($result);
}

приводит к:

Array
(
    [german] => 0.407037037037
    [dutch] => 0.288065843621
    [english] => 0.283333333333
    [danish] => 0.234526748971
)
34
ответ дан scott 14 March 2014 в 11:33
поделиться

Поскольку Google Translate API закрывается как бесплатный сервис, вы можете попробовать эту бесплатную альтернативу, заменяющую Google Translate API:

http://detectlanguage.com

7
ответ дан Laurynas 14 March 2014 в 11:33
поделиться

Вы можете сделать это полностью на стороне клиента с помощью Google AJAX Language API (теперь уже не существует).

С помощью API языка AJAX вы можете переводить и определять язык блоков текста на веб-странице, используя только Javascript. Кроме того, вы можете включить транслитерацию в любом текстовом поле или текстовой области на своей веб-странице. Например, если вы транслитерировали на хинди, этот API позволит пользователям фонетически произносить слова на хинди с использованием английского языка и отображать их в хинди.

Вы можете автоматически определять язык строки

var text = "¿Dónde está el baño?";
google.language.detect(text, function(result) {
  if (!result.error) {
    var language = 'unknown';
    for (l in google.language.Languages) {
      if (google.language.Languages[l] == result.language) {
        language = l;
        break;
      }
    }
    var container = document.getElementById("detection");
    container.innerHTML = text + " is: " + language + "";
  }
});

И переводить любую строку, написанную на одном из поддерживаемых языков (также не существует)

google.language.translate("Hello world", "en", "es", function(result) {
  if (!result.error) {
    var container = document.getElementById("translation");
    container.innerHTML = result.translation;
  }
});
15
ответ дан Matt 14 March 2014 в 11:33
поделиться

Вероятно, вы можете использовать Google Translate API для определения языка и для его перевода при необходимости.

2
ответ дан strager 14 March 2014 в 11:33
поделиться

Вы можете увидеть , как определить язык для строки в php , используя Text_LanguageDetect Pear Package или загрузив его, чтобы использовать его отдельно как обычную библиотеку php.

2
ответ дан adiian 14 March 2014 в 11:33
поделиться

Я знаю, что это старый пост, но вот что я разработал, не найдя никакого жизнеспособного решения.

  • другие предложения слишком тяжелы и слишком громоздки для моей ситуации
  • Я поддерживаю конечное количество языков на моем веб-сайте (на данный момент два ]: 'en' и 'de' - но решение обобщено для большего).
  • Мне нужно правдоподобное предположение о языке сгенерированной пользователем строки, и у меня есть запасной вариант (языковая настройка пользователя).
  • Итак, я хочу найти решение с минимальными ложными срабатываниями - но меня не волнует ложных отрицаний .

Решение использует 20 наиболее распространенных слов в языке, подсчитывает вхождения в стоге сена. Затем он просто сравнивает количество первых и вторых наиболее просчитанных языков. Если номер занявший второе место составляет менее 10% от победителя, победитель получает все.

Кодекс - любые предложения по улучшению скорости приветствуются!

    function getTextLanguage($text, $default) {
      $supported_languages = array(
          'en',
          'de',
      );
      // German word list
      // from http://wortschatz.uni-leipzig.de/Papers/top100de.txt
      $wordList['de'] = array ('der', 'die', 'und', 'in', 'den', 'von', 
          'zu', 'das', 'mit', 'sich', 'des', 'auf', 'für', 'ist', 'im', 
          'dem', 'nicht', 'ein', 'Die', 'eine');
      // English word list
      // from http://en.wikipedia.org/wiki/Most_common_words_in_English
      $wordList['en'] = array ('the', 'be', 'to', 'of', 'and', 'a', 'in', 
          'that', 'have', 'I', 'it', 'for', 'not', 'on', 'with', 'he', 
          'as', 'you', 'do', 'at');
      // clean out the input string - note we don't have any non-ASCII 
      // characters in the word lists... change this if it is not the 
      // case in your language wordlists!
      $text = preg_replace("/[^A-Za-z]/", ' ', $text);
      // count the occurrences of the most frequent words
      foreach ($supported_languages as $language) {
        $counter[$language]=0;
      }
      for ($i = 0; $i < 20; $i++) {
        foreach ($supported_languages as $language) {
          $counter[$language] = $counter[$language] + 
            // I believe this is way faster than fancy RegEx solutions
            substr_count($text, ' ' .$wordList[$language][$i] . ' ');;
        }
      }
      // get max counter value
      // from http://stackoverflow.com/a/1461363
      $max = max($counter);
      $maxs = array_keys($counter, $max);
      // if there are two winners - fall back to default!
      if (count($maxs) == 1) {
        $winner = $maxs[0];
        $second = 0;
        // get runner-up (second place)
        foreach ($supported_languages as $language) {
          if ($language <> $winner) {
            if ($counter[$language]>$second) {
              $second = $counter[$language];
            }
          }
        }
        // apply arbitrary threshold of 10%
        if (($second / $max) < 0.1) {
          return $winner;
        } 
      }
      return $default;
    }
17
ответ дан Swiss Mister 14 March 2014 в 11:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: