2010-12-15 102 views
3

J'essaie d'extraire tous les mots d'une chaîne dans un tableau, mais j'ai des problèmes avec les espaces ( ).Problème lors de la tentative d'extraction des mots d'une chaîne dans PHP

C'est ce que je fais:

//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>"; 

Ce sorties:

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" 
} 

Si je vérifie la source pour la sortie que je vois que les 2 premières valeurs du tableau est &nbsp;.
Peu importe comment j'essaie, je ne peux pas enlever cela de la chaîne. Des idées?

MISE À JOUR:
Après quelques ajustements avec le code je parviens à obtenir la sortie suivante:

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" 

Merci!

ANSWER (pour les paresseux):

Même tu c'est une approche légèrement différente du problème, et il ne répond jamais vraiment pourquoi j'ai eu les problèmes que j'avais ci-dessus (comme les restes de &nbsp; et d'autres supplémentaires bizarre espaces), j'aime bien et c'est beaucoup mieux que mon code original.

Merci à tous ceux qui ont contribué à cela!

//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>"; 
+0

vous que les données réelles contient le   (et non seulement la sortie générée par var_dump)? – JohnSmith

+0

Quelqu'un va poster une version de ceci qui fait la même chose correctement dans environ 6 lignes :) – thirtydot

+0

JohnSmith: Oui. Je reçois la même chose si je fais echo $ data [0] ou echo $ data [1]. – jamietelin

Répondre

2

Ok, la seule chose que vous avez à faire est de remplacer &nbsp; avec un espace comme vous le faites déjà (uniquement si la chaîne contient encore vraiment &nbsp; vérifier @Andy E's answer pour vous assurer que vos données ne ne contiennent aucune entité HTML).

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

Ensuite, vous pouvez utiliser str_word_count pour obtenir les mots:

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

P.S .: Quel est le sens d'appeler d'abord htmlentities puis de le rétablir avec html_entity_decode de toute façon?

Mise à jour: Exemple:

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

impressions

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

documentation lecture aide :)

+0

Malheureusement, str_word_count ne fonctionne pas avec åäö. Il coupe tous les mots comme deux mots quand il frappe å, ​​ä ou ö. – jamietelin

+0

Vous pouvez passer un '$ charlist 'personnalisé comme troisième argument de' str_word_count' - "Une liste de caractères supplémentaires qui seront considérés comme' word '" – thirtydot

+0

@jamietelin: Comme le dit @thirthdot, passez une chaîne avec des caractères supplémentaires cela devrait être considéré comme une partie du mot. Il est décrit dans la documentation à laquelle je suis lié. Croyez-moi, la lecture de documentation aide! –

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

Cela ne fait aucune différence:/ – jamietelin

+0

J'ai fait un test et cela fonctionne pour moi –

1

Au lieu de:

14x str_replace 

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

faire:

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

Alors que 0xC2A0 est l'espace insécable (&nbsp;) et \s est tout caractère blanc couvrant les str_replace appels répétés.

+0

Cela a effectivement fait quelque chose. Mais au lieu d'un espace, je reçois un caractère étrange que je ne peux pas poster ici, il semble. – jamietelin

+1

Le "caractère bizarre" est-il un "0xC2"? –

+0

goreSplatter: Je veux vous embrasser maintenant! J'ai testé "votre personnage" '$ data = str_replace (array (" \ xC2 "), '', $ data);' et ça a marché !!! Que diable est ce caractère '0xC2'? – jamietelin

2

Est-il possible de "coder en double" les parties &nbsp; existantes de la chaîne? Vous appelez htmlentities sur la chaîne avant html_entity_decode, donc tous les caractères &nbsp; existants deviendront &amp;nbsp;. Vous pouvez empêcher htmlentities de double codage en fournissant false en tant que quatrième paramètre.

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

Aussi, nu à l'esprit que vous pouvez passer un tableau pour les matches de str_replace:

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

peut-être vous devriez essayer ceci: http://php.net/manual/en/function.str-word-count.php

J'ai fait quelque chose proche de votre objectif récemment:

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

Au revoir.

+0

Malheureusement, str_word_count ne fonctionne pas avec åäö. Il coupe tous les mots comme deux mots quand il frappe å, ​​ä ou ö. – jamietelin

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

Mise à jour

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); 
+0

Merci pour votre effort ?! Mais cela n'a rien fait. C'est exactement ce que je fais déjà. – jamietelin