Intereting Posts
PHP Неустранимая ошибка: не удается сломать / продолжить Как найти наиболее распространенные слова в базе данных MySQL и средний второй столбец PHP Игнорирование моего max_execution_time Дата истечения срока действия PHP Могу ли я сделать исключение в цикле for, если память превышает этот цикл XML: сохранение нескольких значений дочернего узла в php-массив Sphinx search sql_attr_multi – где условие Как удалить строки строки (без символов!) Из строки? Запуск нескольких запросов в модели в codeigniter Laravel 5, View :: Поделиться Использование простых примеров абстрактного класса в реальном мире Утвердить несколько условий в одном тесте или разбить на несколько тестов? Как обеспечить, чтобы значения атрибутов, содержащие кавычки, не нарушали форматирование? Переходы Doctrine можно использовать в производственных приложениях? Переопределение метода и строгие стандарты

Извлечение урду / арабских фраз / предложений из строки

Я хочу извлечь фразы из урду из строки, представленной пользователем в PHP. Для этого я попробовал следующий тестовый код:

$pattern = "#([\x{0600}-\x{06FF}]+\s*)+#u"; if (preg_match_all($pattern, $string, $matches, PREG_SET_ORDER)) { print_r($matches); } else { echo 'No matches.'; } 

Теперь, если, например, $string содержит

In his books (some of which include دنیا گول ہے, آوارہ گرد کی ڈائری, and ابن بطوطہ کے تعاقب میں), Ibn-e-Insha has told amusing stories of his travels.

Я получаю следующий вывод:

 массив
 (
     [0] => Массив
         (
             [0] => دنیا گول ہے
             [1] => ہے
         )

     [1] => Массив
         (
             [0] => آوارہ گرد کی ڈائری
             [1] => ڈائری
         )

     [2] => Массив
         (
             [0] => ابن بطوطہ کے تعاقب میں
             [1] => میں
         )

 )

Несмотря на то, что я получаю мои желаемые матчи ( دنیا گول ہے , آوارہ گرد کی ڈائری и ابن بطوطہ کے تعاقب میں ), я также получаю нежелательные ( ہے , ڈائری и میں – каждый из которых на самом деле является последним словом его фразы ). Может ли кто-нибудь указать, как я могу избежать нежелательных матчей?

Это связано с тем, что группа захвата ([\x{0600}-\x{06FF}]+\s*) сопоставляется несколько раз, каждый раз переписывая то, что соответствовало предыдущему времени. Вы можете получить ожидаемый результат, просто переведя его в группу, не (?:[\x{0600}-\x{06FF}]+\s*) захватом – (?:[\x{0600}-\x{06FF}]+\s*) но вот более правильная альтернатива:

 $pattern = "#(?:[\x{0600}-\x{06FF}]+(?:\s+[\x{0600}-\x{06FF}]+)*)#u"; 

Первый [\x{0600}-\x{06FF}]+ соответствует первому слову, затем, если есть пробелы, за которыми следует другое слово, (?:\s+[\x{0600}-\x{06FF}]+)* соответствует ему и любым последующим словам. Но после последнего слова это не соответствует пробелу, который, как я полагаю, вам не нужен.