在PHP中尝试从字符串中提取单词时出现问题

时间:2010-12-15 13:15:10

标签: php parsing string-parsing

我正在尝试将字符串中的所有单词提取到数组中,但是我遇到了一些空格问题( )。

这就是我的所作所为:

//Clean data to text only
$data = strip_tags($data);
$data = htmlentities($data, ENT_QUOTES, 'UTF-8');
$data = html_entity_decode($data, ENT_QUOTES, 'UTF-8');
$data = htmlspecialchars_decode($data);
$data = mb_strtolower($data, 'UTF-8');

//Clean up text from special chrs I don't want as words
$data = str_replace(',', '', $data);
$data = str_replace('.', '', $data);
$data = str_replace(':', '', $data);
$data = str_replace(';', '', $data);
$data = str_replace('*', '', $data);
$data = str_replace('?', '', $data);
$data = str_replace('!', '', $data);
$data = str_replace('-', ' ', $data);
$data = str_replace("\n", ' ', $data);
$data = str_replace("\r", ' ', $data);
$data = str_replace("\t", ' ', $data);
$data = str_replace("\0", ' ', $data);
$data = str_replace("\x0B", ' ', $data);
$data = str_replace(" ", ' ', $data);

//Clean up duplicated spaces
do {
   $data = str_replace('  ', ' ', $data);
} while(strpos($data, '  ') !== false);

//Make array
$clean_data = explode(' ', $data);

echo "<pre>";
var_dump($clean_data);
echo "</pre>";

输出:

array(58) {
  [0]=>
  string(5) " "
  [1]=>
  string(5) " "
  [2]=>
  string(11) "anläggning"
  [3]=>
  string(3) "med"
  [4]=>
  string(3) "den"
  [5]=>
  string(10) "erfarenhet"
  [6]=>
  string(3) "som"
}

如果我检查输出的来源,我会看到前两个数组的值是&nbsp; 无论我如何尝试,我都无法从字符串中删除它。有什么想法吗?

更新
经过一些代码调整后,我设法得到以下输出:

array(56) {
  [0]=>
  string(1) "�" //Notice change. Instead of string length 5 it now says 1. But still its garbage.
  [1]=>
  string(1) "�"
  [2]=>
  string(11) "anläggning"
  [3]=>
  string(3) "med"
  [4]=>
  string(3) "den"
  [5]=>
  string(10) "erfarenhet"
  [6]=>
  string(3) "som"
  [7]=>
  string(5) "finns"
  [8]=>
  string(4) "inom"

谢谢!

答案(对于懒人):

即使你对这个问题的解决方法略有不同,但它从来没有真正回答为什么我遇到了上面遇到的问题(比如剩下的&nbsp;和其他奇怪的空间),我喜欢它,它是一个比我原来的代码好很多。

感谢所有为此做出贡献的人!

//Clean data to text only
$data = strip_tags($data);
$data = html_entity_decode($data, ENT_QUOTES, 'UTF-8');
$data = htmlspecialchars_decode($data);
$data = mb_strtolower($data, 'UTF-8');

//Clean up text from special chrs
$data = str_replace(array("-"), ' ', $data);    

$clean_data = str_word_count($data, 1, 'äöå');

echo "<pre>";
var_dump($clean_data);
echo "</pre>";

6 个答案:

答案 0 :(得分:2)

好的,你唯一需要做的就是用你已经做过的空格替换&nbsp;(只有当字符串确实包含&nbsp;时才检查@Andy E's answer以确保您的数据不包含任何HTML实体。):

$data = str_replace("&nbsp;", ' ', $data);

然后您可以使用str_word_count来获取字词:

$words = str_word_count($data, 1, 'äöåÄÖÅ');

P.S。:首先调用htmlentities然后再使用html_entity_decode再次恢复它的感觉是什么?

更新:示例:

$str = '      anläggning med den      erfahrenhet som åååÅ ÅÅ';
print_r(str_word_count($str, 1, 'äöåÄÖÅ'));

打印

Array
(
    [0] => anläggning
    [1] => med
    [2] => den
    [3] => erfahrenhet
    [4] => som
    [5] => åååÅ
    [6] => ÅÅ
)

阅读文档有助于:)

答案 1 :(得分:2)

是否有可能对字符串的任何现有&nbsp;部分进行“双重编码”?您在htmlentities之前的字符串上调用html_entity_decode,因此任何现有的&nbsp;字符都将变为&amp;nbsp;。您可以通过提供htmlentities作为第四个参数来阻止false进行双重编码。

$data = htmlentities($data, ENT_QUOTES, 'UTF-8', false);
$data = html_entity_decode($data, ENT_QUOTES, 'UTF-8');

另外,请记住,您可以为str_replace中的匹配传递数组:

$data = str_replace(array(',','.',':',';','*','?','!','-'), '', $data);

答案 2 :(得分:1)

而不是:

14x str_replace

do {
   $data = str_replace('  ', ' ', $data);
} while(strpos($data, '  ') !== false);

做的:

$data = preg_replace('/[.*,:;?!]/', '', $data);
$data = preg_replace('/(?:\xC2\xA0|\s{2,}|-)/', ' ', $data);

0xC2A0是不间断的空格(&nbsp;)而\s是覆盖重复的str_replace电话的任何空白字符。

答案 3 :(得分:1)

print_r( explode(" ", $data));

<强>更新

define("WORD_COUNT_MASK", "/\p{L}[\p{L}\p{Mn}\p{Pd}'\x{2019}]*/u");

function str_word_count_utf8($str)
{
     preg_match_all(WORD_COUNT_MASK, $str, $matches);
     print_r( $matches);
}
str_word_count_utf8( $str);

答案 4 :(得分:0)

$data = '&nbsp; cesadasdsadas <br /> &nbsp; dsadsadas';
$data = preg_replace('/&nbsp;/', ' ', $data);
var_dump($data);

答案 5 :(得分:0)

也许你应该试试这个:http://php.net/manual/en/function.str-word-count.php

我最近接近你的目标:

    $words = array_unique(str_word_count($CONTENT." ".$TITLE, 1));
    sort($words);
    $words = addslashes (implode(" ", array_values($words)));

再见。