Регулярное выражение для обнаружения чисел, написанных как слова - вход UTF-8

StackOverflow https://stackoverflow.com/questions/3630082

Вопрос

Спасибо за ответы на:

«Регулярное выражение для обнаружения чисел, написанных как слова»:

регулярное выражение для обнаружения чисел, написанных как слова

Теперь у меня есть эта работа, однако у меня такое же требование, но числа, как слова на арабском языке (или любой другой UTF-8), а не на английском, поэтому:

if (preg_match("/\p{L}\b(?:(?:واحد|اثنان|ثلاثة|أربعة|خمسة|ستة|سبعة|ثمانية|تسعة|صفر|عشرة)\b\s*?){4}/", $str, $matches) > 0) 
   return true;

Не работает - я погугулировал, и, кажется, есть несколько вопросов с reg_match и utf-8 string, но я не мог получить ни одно из предложений, на которые работают. Любая помощь очень ценится.

Это было полезно?

Решение

Обратите внимание, что \b не может работать, как вы ожидаете. \b Указывает а Слово граница, но то, что считается словом символ PCRE, зависит от того, в какой локали скрипт работает (посмотрите на дно PCRE Escape Sequences. Ручная страница):

Персонаж «Word» - это любая буква или цифра или символ подчеркивания, то есть любой символ, который может быть частью Perl «Word». Определение букв и цифр контролируется таблицами символов PCRE и может варьироваться в зависимости от того, если происходит сопоставление с локалью. Например, в «FR» (французском) локале, некоторые коды символов, превышающие 128, используются для акцентированных букв, и они сопоставляются W.

Вы также можете прочитать Обработка UTF-8 с PHP (раздел на PCRE в частности).

Вместо этого вы могли бы использовать осмотреться В сочетании с свойством символов Unicode для эмуляции границы слова: (?<=\P{L}). Отказ Это утверждает, что предыдущий персонаж нет Уникоде «Письмо».

Так что все вместе это будет выглядеть так:

/(?<=\P{L})(?:(?:واحد|اثنان|ثلاثة|أربعة|خمسة|ستة|سبعة|ثمانية|تسعة|صفر|عشرة)\s*?){4}/

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

преобразовать оба рисунка, так и $str к windows-1256, сделайте соответствие, затем конвертировать $matches Предметы обратно (при необходимости), это решение, которое я пришел в течение некоторого времени после страданий.

$pattern="/\p{L}\b(?:(?:واحد|اثنان|ثلاثة|أربعة|خمسة|ستة|سبعة|ثمانية|تسعة|صفر|عشرة)\b\s*?){4}/";
$pattern_windows1265 = iconv('utf-8', 'windows-1256', $pattern);
$str_windows1265 = iconv('utf-8', 'windows-1256', $str);
if (preg_match($pattern_windows1265, $str_windows1265, $matches) > 0) 
   return true;

Вот пример теста для проверки, если конверсия Unicode позволяет арабским буквам совпадать в preg_match:

<?php
$pattern="/(واحد|اثنان|ثلاثة|أربعة|خمسة|ستة|سبعة|ثمانية|تسعة|صفر|عشرة)/";
$pattern_windows1265 = iconv('utf-8', 'windows-1256', $pattern);


$test_cases=array(
    'لدي أربعة أولاد',
    'قفز الثعلب فوق الشجرة',
    'عندي خمسة أرانب',
);
foreach ($test_cases as $str) {
    $str_windows1265 = iconv('utf-8', 'windows-1256', $str);

    if (preg_match($pattern_windows1265, $str_windows1265, $matches) > 0) {
        echo $str, '<br />';
    }
}

При выполнении он будет выводиться:

لدي أربعة أولاد
لدي خمسة أرانب

Я удалил некоторых из шаблонов, чтобы проверить, правильная проверка на арабских работах, которая, кажется, работает.

Вы можете использовать модификатор шаблона u использовать любой поддерживаемый язык UTF-8.

if (preg_match("/\p{L}\b(?:(?:واحد|اثنان|ثلاثة|أربعة|خمسة|ستة|سبعة|ثمانية|تسعة|صفر|عشرة)\b\s*?){4}/u", $str, $matches) > 0) 

Ресурсы :

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top