Разделить текст на отдельные слова - PullRequest
9 голосов
/ 26 апреля 2009

Я хотел бы разбить текст на отдельные слова, используя PHP. У вас есть идеи, как этого добиться?

Мой подход:

function tokenizer($text) {
    $text = trim(strtolower($text));
    $punctuation = '/[^a-z0-9äöüß-]/';
    $result = preg_split($punctuation, $text, -1, PREG_SPLIT_NO_EMPTY);
    for ($i = 0; $i < count($result); $i++) {
        $result[$i] = trim($result[$i]);
    }
    return $result; // contains the single words
}
$text = 'This is an example text, it contains commas and full-stops. Exclamation marks, too! Question marks? All punctuation marks you know.';
print_r(tokenizer($text));

Это хороший подход? Есть ли у вас идеи по улучшению?

Заранее спасибо!

Ответы [ 6 ]

29 голосов
/ 26 апреля 2009

Используйте класс \ p {P}, который соответствует любому знаку препинания в Юникоде, в сочетании с классом \ s пробелов.

$result = preg_split('/((^\p{P}+)|(\p{P}*\s+\p{P}*)|(\p{P}+$))/', $text, -1, PREG_SPLIT_NO_EMPTY);

Это разделит группу из одного или нескольких пробельных символов, но также засосет любые окружающие знаки препинания. Он также соответствует знакам препинания в начале или конце строки. Это различает такие случаи, как «не» и «он сказал: ой!»

12 голосов
/ 26 апреля 2009

Tokenize - strtok .

<?php
$text = 'This is an example text, it contains commas and full stops. Exclamation marks, too! Question marks? All punctuation marks you know.';
$delim = ' \n\t,.!?:;';

$tok = strtok($text, $delim);

while ($tok !== false) {
    echo "Word=$tok<br />";
    $tok = strtok($delim);
}
?>
3 голосов
/ 26 апреля 2009

Я бы сначала сделал строку в нижнем регистре, прежде чем разделить ее. Это сделало бы модификатор i и последующую обработку массива ненужными. Кроме того, я бы использовал сокращение \W для несловесных символов и добавил бы множитель +.

$text = 'This is an example text, it contains commas and full stops. Exclamation marks, too! Question marks? All punctuation marks you know.';
$result = preg_split('/\W+/', strtolower($text), -1, PREG_SPLIT_NO_EMPTY);

Редактировать Использовать свойства символов Юникода вместо \W , как предложил marcog . Нечто подобное [\p{P}\p{Z}] (знаки препинания и символы-разделители) будет охватывать символы более специфичные, чем \W.

1 голос
/ 10 октября 2012

Вы также можете использовать метод разнесения: http://php.net/manual/en/function.explode.php

$words = explode(" ", $sentence);
1 голос
/ 26 апреля 2009

Вы также можете использовать функцию PHP strtok () для получения строковых токенов из вашей большой строки. Вы можете использовать это так:

 $result = array();
 // your original string
 $text = 'This is an example text, it contains commas and full stops. Exclamation marks, too! Question marks? All punctuation marks you know.';
 // you pass strtok() your string, and a delimiter to specify how tokens are separated. words are seperated by a space.
 $word = strtok($text,' ');
 while ( $word !== false ) {
     $result[] = $word;
     $word = strtok(' ');
 }

см. Больше документации php для strtok ()

1 голос
/ 26 апреля 2009

Do:

str_word_count($text, 1);

Или, если вам нужна поддержка юникода:

function str_word_count_Helper($string, $format = 0, $search = null)
{
    $result = array();
    $matches = array();

    if (preg_match_all('~[\p{L}\p{Mn}\p{Pd}\'\x{2019}' . preg_quote($search, '~') . ']+~u', $string, $matches) > 0)
    {
        $result = $matches[0];
    }

    if ($format == 0)
    {
        return count($result);
    }

    return $result;
}
...