Подтвердить что ты не робот

Обнаружение языка из строки в PHP

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

4b9b3361

Ответ 1

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

С помощью любого метода вы просто получаете обоснованное предположение. Существуют некоторые связанные с математикой статьи там

Ответ 2

Я использовал Text_LanguageDetect pear package с некоторыми разумными результатами. Он прост в использовании и имеет небольшую 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
)

Ответ 3

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

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

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

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

Ответ 4

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

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

Ответ 5

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

http://detectlanguage.com

Ответ 7

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

Ответ 8

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

Я могу порекомендовать вам попробовать Yandex Translate 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>";
?>

Ответ 9

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

  • Собственные существительные могут не обрабатываться хорошо
  • орфографические ошибки могут нарушить ваши поисковые запросы.
  • аббревиатуры типа "lol" или "b4" необязательно будут в словаре

Ответ 11

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

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

Ответ 13

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

Ответ 14

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

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;  

Ответ 15

Text_LanguageDetect pear package произвел ужасные результаты: "роскошные апартаменты в центре города" обнаружены как португальцы...

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

Ниже приведена супер простая функция, которая использует file_get_contents для загрузки lang, обнаруженного 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 и явно использовать библиотеку.