Dividere il text in parole problema PHP, problema complicato

Sto cercando di dividere il text in parole:

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

che funziona abbastanza bene con le stringhe, ma sono bloccato in alcuni casi in cui devo fare dei numbers.

Ad esempio, se ho il text "Guarda questo. Il mio punteggio è 3.14, e ne sono felice". Ora la matrix è

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

Quindi anche il 3.14 è diviso in 3 e 14 che non dovrebbe accadere nel mio caso. Intendo dire che il punto dovrebbe dividere due stringhe ma non due numbers. Dovrebbe essere come:

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

Ma non ho idea di come evitare questo caso!

Qualcuno ha idea di come risolvere questo problema?

Grazie, Granito

Oppure usa 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)); arrays(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" } 

Dai un'occhiata a strtok . Ti consente di modificare i token di analisi in modo dinamico, in modo da poter spezzare la corda manualmente in un ciclo while, spingendo each parola divisa in una matrix.

La mia prima idea era preg_match_all('/\w+/', $string, $matches); ma questo dà un risultato simile a quello che hai. Il problema è che i numbers separati da un punto sono molto ambigui. Può significare sia il punto decimale che la fine della frase, quindi abbiamo bisogno di un modo per cambiare la string in modo da eliminare il doppio significato.

Per esempio in questa frase abbiamo diverse parti che vorremmo mantenere come una sola parola: "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." .

Iniziamo creando un dictionary search-> replace per codificare le eccezioni in qualcosa che non si dividerà:

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

Successivamente, codifichiamo le eccezioni:

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

Dividi la string:

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

E riconvertire la parola codificata:

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

$matches ora contiene la frase originale divisa in parole con le giuste eccezioni.

È ansible rendere la regex utilizzata in eccezioni semplice o complessa come si desidera, ma alcune ambiguità verranno sempre superate, ad esempio due sentenze con la prima che termina e la successiva che inizia con un numero: Number of the counting shall be 3.3 only and nothing but the 3.5 is right out..

Usa ". ", Invece di ".", In $delimiterList .