Определить язык из строки в PHP - PullRequest
29 голосов
/ 18 сентября 2009

В PHP есть способ определить язык строки? Предположим, строка в формате UTF-8.

Ответы [ 15 ]

34 голосов
/ 05 апреля 2010

Я использовал пакет 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
)
17 голосов
/ 14 марта 2014

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

  • другие предложения слишком тяжелы и громоздки для моей ситуации
  • Я поддерживаю конечное число языков на моем веб-сайте (в настоящее время два : '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 голосов
/ 18 сентября 2009

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

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

15 голосов
/ 18 сентября 2009

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

С помощью AJAX Language API вы можете переводить и определять язык блоков текста на веб-странице, используя только 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;
  }
});
7 голосов
/ 14 ноября 2011

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

http://detectlanguage.com

4 голосов
/ 13 мая 2016

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

Я могу порекомендовать вам попробовать Яндекс Перевод 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>";
?>
2 голосов
/ 08 ноября 2017

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 голосов
/ 05 мая 2012

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

2 голосов
/ 18 сентября 2009

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

1 голос
/ 22 августа 2018

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

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

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

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

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

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

...