web-dev-qa-db-fra.com

php explode: divise la chaîne en mots en utilisant un délimiteur d'espace

$str = "This is a    string";
$words = explode(" ", $str);

Fonctionne bien, mais les espaces vont toujours dans le tableau:

$words === array ('This', 'is', 'a', '', '', '', 'string');//true

Je préférerais avoir des mots uniquement sans espaces et garder les informations sur le nombre d'espaces séparées.

$words === array ('This', 'is', 'a', 'string');//true
$spaces === array(1,1,4);//true

Vient d'ajouter: (1, 1, 4) signifie un espace après le premier mot, un espace après le deuxième mot et 4 espaces après le troisième mot.

Existe-t-il un moyen de le faire rapidement?

Merci.

19
Haradzieniec

Pour diviser la chaîne en un tableau, vous devez utiliser preg_split :

$string = 'This is a    string';
$data   = preg_split('/\s+/', $string);

Votre deuxième partie (comptage des espaces):

$string = 'This is a    string';
preg_match_all('/\s+/', $string, $matches);
$result = array_map('strlen', $matches[0]);// [1, 1, 4]
29
Alma Do

$financialYear = 2015-2016;

$test = explode('-',$financialYear);
echo $test[0]; // 2015
echo $test[1]; // 2016
2
Raj

Voici une façon, de fractionner la chaîne et d'exécuter une expression régulière une fois, puis d'analyser les résultats pour voir quels segments ont été capturés en tant que fractionnement (et donc uniquement les espaces blancs), ou lesquels sont des mots:

$temp = preg_split('/(\s+)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

$spaces = array();
$words = array_reduce( $temp, function( &$result, $item) use ( &$spaces) {
    if( strlen( trim( $item)) === 0) {
        $spaces[] = strlen( $item);
    } else {
        $result[] = $item;
    }
    return $result;
}, array());

Vous pouvez voir à partir de cette démo que $words est:

Array
(
    [0] => This
    [1] => is
    [2] => a
    [3] => string
)

Et $spaces est:

Array
(
    [0] => 1
    [1] => 1
    [2] => 4
)
2
nickb

Vous pouvez utiliser preg_split() pour le premier tableau:

$str   = 'This is a    string';
$words = preg_split('#\s+#', $str);

Et preg_match_all() pour le tableau $spaces:

preg_match_all('#\s+#', $str, $m);
$spaces = array_map('strlen', $m[0]);
1
silkfire

Une autre façon de le faire serait d'utiliser foreach loop.

$str = "This is a    string";
$words = explode(" ", $str);
$spaces=array();
$others=array();
foreach($words as $Word)
{
if($Word==' ')
{
array_Push($spaces,$Word);
}
else
{
array_Push($others,$Word);
}
}
1
Ahmar Ali

Voici les résultats des tests de performances:

$str = "This is a    string";

var_dump(time());

for ($i=1;$i<100000;$i++){
//Alma Do Mundo  - the winner
$rgData = preg_split('/\s+/', $str);


preg_match_all('/\s+/', $str, $rgMatches);
$rgResult = array_map('strlen', $rgMatches[0]);// [1,1,4]


}
print_r($rgData); print_r( $rgResult);
var_dump(time());




for ($i=1;$i<100000;$i++){
//nickb
$temp = preg_split('/(\s+)/', $str, -1,PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$spaces = array();
$words = array_reduce( $temp, function( &$result, $item) use ( &$spaces) {
    if( strlen( trim( $item)) === 0) {
        $spaces[] = strlen( $item);
    } else {
        $result[] = $item;
    }
    return $result;
}, array());
}


print_r( $words); print_r( $spaces);
var_dump(time());

int (1378392870) Array ([0] => This [1] => is [2] => a [3] => string) Array ([0] => 1 [1] => 1 [2] => 4) int (1378392871) Array ([0] => This [1] => is [2] => a [3] => string) Array ([0] => 1 [1] => 1 [2] => 4) int (1378392873)

0
Haradzieniec