Разделить текст на проблемы слов PHP, сложная проблема

Я пытаюсь разделить текст на слова:

$delimiterList = array(" ", ".", "-", ",", ";", "_", ":", "!", "?", "/", "(", ")", "[", "]", "{", "}", "<", ">", "\r", "\n", '"'); $words = mb_split($delimiterList, $string); 

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

  • как проверить, включен ли завиток или отключен
  • Конструкция динамического класса Php
  • Как эхо-массив в PHP?
  • Запустить php-скрипт как процесс демона
  • Перевод даты PHP () для многоязычного сайта
  • Как отправить PHPSESSID в URL?
  • Например, если у меня есть текст «Посмотрите на это. Мой результат равен 3,14, и я доволен этим». Теперь массив

     [0]=>Look, [1]=>at, [2]=>this, [3]=>My, [4]=>score, [5]=>is, [6]=>3, [7]=>14, [8]=>and, .... 

    Затем также 3.14 делится на 3 и 14, что не должно произойти в моем случае. Я имею в виду, что точка должна делить две строки, но не два числа. Это должно выглядеть так:

     [0]=>Look, [1]=>at, [2]=>this, [3]=>My, [4]=>score, [5]=>is, [6]=>3.14, [7]=>and, .... 

    Но у меня нет идеи, как избежать подобных случаев!

    Кто-нибудь знает, как решить эту проблему?

    Танк, Гранит

    4 Solutions collect form web for “Разделить текст на проблемы слов PHP, сложная проблема”

    Или используйте regex 🙂

     <?php $str = "Look at this.My score is 3.14, and I am happy about it."; // alternative to handle Marko's example (updated) // /([\s_;?!\/\(\)\[\]{}<>\r\n"]|\.$|(?<=\D)[:,.\-]|[:,.\-](?=\D))/ var_dump(preg_split('/([\s\-_,:;?!\/\(\)\[\]{}<>\r\n"]|(?<!\d)\.(?!\d))/', $str, null, PREG_SPLIT_NO_EMPTY)); array(13) { [0]=> string(4) "Look" [1]=> string(2) "at" [2]=> string(4) "this" [3]=> string(2) "My" [4]=> string(5) "score" [5]=> string(2) "is" [6]=> string(4) "3.14" [7]=> string(3) "and" [8]=> string(1) "I" [9]=> string(2) "am" [10]=> string(5) "happy" [11]=> string(5) "about" [12]=> string(2) "it" } 

    Взгляните на strtok . Он позволяет динамически изменять токены синтаксического разбора, поэтому вы можете разбить строку вручную в цикле while, нажав каждое разделенное слово в массив.

    Моя первая идея была preg_match_all('/\w+/', $string, $matches); но это дает аналогичный результат тому, который у вас есть. Проблема в том, что числа, разделенные точкой, очень неоднозначны. Это может означать как десятичную точку, так и конец предложения, поэтому нам нужен способ изменить строку таким образом, чтобы исключить двойной смысл.

    Например, в этом предложении у нас есть несколько частей, которые мы хотели бы оставить как одно слово: "Look at this.My score is 3.14, and I am happy about it. It's not 334,3 and today's not 2009-12-12 11:12:13." ,

    Мы начинаем с создания словаря search-> replace для кодирования исключений во что-то, что не будет разделено:

     $encode = array( '/(\d+?)\.(\d+?)/' => '\\1DOT\\2', '/(\d+?),(\d+?)/' => '\\1COMMA\\2', '/(\d+?)-(\d+?)-(\d+?) (\d+?):(\d+?):(\d+?)/' => '\\1DASH\\2DASH\\3SPACE\\4COLON\\5COLON\\6' ); 

    Затем мы кодируем исключения:

     foreach ($encode as $regex => $repl) { $string = preg_replace($regex, $repl, $string); } 

    Разделить строку:

     preg_match_all('/\w+/', $string, $matches); 

    И преобразуйте закодированное слово назад:

     $decode = array( 'search' => array('DOT', 'COMMA', 'DASH', 'SPACE', 'COLON'), 'replace' => array('.', ',', '-', ' ', ':' ) ); foreach ($matches as $k => $v) { $matches[$k] = str_replace($decode['search'], $decode['replace'], $v); } 

    $matches теперь содержит исходное предложение, разделенное на слова с правильными исключениями.

    Вы можете сделать регулярное выражение, используемое в исключениях, простым или сложным, как вам нравится, но некоторая двусмысленность всегда будет проходить, например, два предложения с первым завершающим, а следующее, начинающееся с числа: Number of the counting shall be 3.3 only and nothing but the 3.5 is right out..

    Используйте ". ", Вместо ".", В $delimiterList .

    PHP is the Best Programming Language in the world.