2009-09-17 2 views
25

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

+1

Вы хотите проверить, есть ли в строке символы, отличные от английского? Можете ли вы определить, что такое «английский»? – strager

+3

«Проблема с французами - у них нет слова для предпринимателя» –

+1

В принципе, что я хочу сделать, у меня есть массив входящих комментариев пользователей, каждый из которых может быть написан на разных языках. на бэкэнде PHP, я хочу установить флаг, если комментарий не является английским (например, на французском или японском), и интерфейс будет показывать кнопку перевода, если флаг установлен – Beier

ответ

15

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

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

1

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

  • собственные имена не могут быть обработаны хорошо
  • орфографические ошибки могут нарушить ваши поиски
  • аббревиатуры, как «Круто» или «b4» не обязательно быть в словаре
+0

"lol" - акроним. =] – strager

+12

@strager: и аббревиатура является аббревиатурой типа: http://en.wiktionary.org/wiki/acronym :) –

2

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

+4

Поскольку они удаляют это как бесплатный вариант, это может быть не вариант. Кроме того, перевод комментария может быть плохой идеей не только из-за эффекта «потерянного перевода», но и из-за того, что пользователь вообще не может читать английский. Сколько бы это вышло, если сайт перевел ваш комментарий на язык, который вы не могли прочитать? –

+0

В GitHub есть бесплатный пакет переводов, который позволяет вам определять язык (начиная с версии 3.0). Https://github.com/Stichoza/google-translate-php – Stichoza

15

Вы можете сделать это полностью на стороне клиента с Google's 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 + ""; 
    } 
}); 

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

google.language.translate("Hello world", "en", "es", function(result) { 
    if (!result.error) { 
    var container = document.getElementById("translation"); 
    container.innerHTML = result.translation; 
    } 
}); 
+6

Оригинальный API Google Language теперь обесценивается, а API2 - оплачено. Кроме того, для такого простого использования персонажи $ 20/1M кажутся дорогим. –

+0

Вы получаете 300 $ в свободном кредите, я предоставил пример PHP ниже –

1

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

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

33

Я использовал 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 
) 
+0

Можете ли вы объяснить, как я могу установить этот пакет на общий хост? Это дает мне много проблем ... Я думаю, что для меня это намного более полезно, чем API для перевода Google, поскольку Google ограничивает количество вызовов так много. – Roozbeh15

+0

Не работает ли эта библиотека с php5? – Roozbeh15

+0

@scott, его не работает для меня :( –

0

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

6

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

http://detectlanguage.com

+0

Мне это нравится, но, глядя на их термины, грустно заставляет меня нервничать из-за их использования. –

1

Вы можете увидеть how to detect language for a string in php с помощью Text_LanguageDetect груши Пакет или загрузка, чтобы использовать его отдельно, как обычная библиотека php.

+0

это нужно больше upvotes, работал как шарм! Спасибо –

+0

действительно попробовал это немного больше, и он не работает очень хорошо ... «роскошные апартаменты в центре города» обнаружены как португальский. Ни «роскошь», ни «центр города» Португальское слово .. ужасно .. –

14

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

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

Решение использует 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; 
    } 
+0

Мне нравится ваш подход и думаю, что он дает хорошее образованное предположение. Есть некоторые (небольшие) проблемы с вашим кодом li ke он не будет считать слова перед точкой (.) или запятой (,) и т. д. – Nin

+0

@Nin: да, это будет считать эти слова ('.'и', 'заменяются пробелами и, следовательно, становятся« разделителями слов »). Но вам действительно нужно внести несколько корректировок, если строки в ваших списках слов содержат символы, отличные от ASCII. –

+0

Дух, ты прав. Я не обращал внимания. Я уже изменил его, чтобы использовать array_count_values ​​(str_word_count ($ text, 1)). Это кажется немного быстрее (микро) для небольших строк, где я их использую. – Nin

2

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

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

попытаться использовать 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

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"]; 
} 

Execute:

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

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

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