Question

Comment puis-je faire exploser la chaîne suivante:

Lorem ipsum "dolor sit amet" consectetur "adipiscing elit" dolor

dans

array("Lorem", "ipsum", "dolor sit amet", "consectetur", "adipiscing elit", "dolor")

Alors que le texte en cours est traité comme un seul mot.

Voici ce que j'ai pour l'instant:

$mytext = "Lorem ipsum %22dolor sit amet%22 consectetur %22adipiscing elit%22 dolor"
$noquotes = str_replace("%22", "", $mytext");
$newarray = explode(" ", $noquotes);

mais mon code divise chaque mot dans un tableau. Comment puis-je faire des mots entre guillemets traités comme un seul mot?

Était-ce utile?

La solution

Vous pouvez utiliser un preg_match_all(...):

$text = 'Lorem ipsum "dolor sit amet" consectetur "adipiscing \\"elit" dolor';
preg_match_all('/"(?:\\\\.|[^\\\\"])*"|\S+/', $text, $matches);
print_r($matches);

qui produira:

Array
(
    [0] => Array
        (
            [0] => Lorem
            [1] => ipsum
            [2] => "dolor sit amet"
            [3] => consectetur
            [4] => "adipiscing \"elit"
            [5] => dolor
        )

)

Et comme vous pouvez le voir, il représente également des citations échappées à l'intérieur des chaînes entre guillemets.

EDIT

Une brève explication:

"           # match the character '"'
(?:         # start non-capture group 1 
  \\        #   match the character '\'
  .         #   match any character except line breaks
  |         #   OR
  [^\\"]    #   match any character except '\' and '"'
)*          # end non-capture group 1 and repeat it zero or more times
"           # match the character '"'
|           # OR
\S+         # match a non-whitespace character: [^\s] and repeat it one or more times

Et en cas d'appariement %22 au lieu de guillemets doubles, vous feriez:

preg_match_all('/%22(?:\\\\.|(?!%22).)*%22|\S+/', $text, $matches);

Autres conseils

Cela aurait été beaucoup plus facile avec str_getcsv() .

$test = 'Lorem ipsum "dolor sit amet" consectetur "adipiscing elit" dolor';
var_dump(str_getcsv($test, ' '));

Vous donne

array(6) {
  [0]=>
  string(5) "Lorem"
  [1]=>
  string(5) "ipsum"
  [2]=>
  string(14) "dolor sit amet"
  [3]=>
  string(11) "consectetur"
  [4]=>
  string(15) "adipiscing elit"
  [5]=>
  string(5) "dolor"
}

Vous pouvez également essayer cette fonction multiple exploser

function multiexplode ($delimiters,$string)
{

$ready = str_replace($delimiters, $delimiters[0], $string);
$launch = explode($delimiters[0], $ready);
return  $launch;
}

$text = "here is a sample: this text, and this will be exploded. this also | this one too :)";
$exploded = multiexplode(array(",",".","|",":"),$text);

print_r($exploded);

Dans certains cas, le peu connu token_get_all() pourrait se révéler utile :

$tokens = token_get_all("<?php $text ?>");
$separator = ' ';
$items = array();
$item = "";
$last = count($tokens) - 1;
foreach($tokens as $index => $token) {
    if($index != 0 && $index != $last) {
        if(count($token) == 3) {
            if($token[0] == T_CONSTANT_ENCAPSED_STRING) {
                $token = substr($token[1], 1, -1);
            } else {
                $token = $token[1];
            }
        }
        if($token == $separator) {
            $items[] = $item;
            $item = "";
        } else {
            $item .= $token;
        }
    }
}

Résultats:

Array
(
    [0] => Lorem
    [1] => ipsum
    [2] => dolor sit amet
    [3] => consectetur
    [4] => adipiscing elit
    [5] => dolor
)

Je suis venu ici avec un problème de division de chaîne complexe semblable à, mais aucune des réponses ici a fait exactement ce que je voulais - j'ai donc écrit mon

.

Je signale ici juste au cas où il est utile à quelqu'un d'autre.

Ceci est probablement une façon très lente et inefficace de le faire - mais ça marche pour moi

.
function explode_adv($openers, $closers, $togglers, $delimiters, $str)
{
    $chars = str_split($str);
    $parts = [];
    $nextpart = "";
    $toggle_states = array_fill_keys($togglers, false); // true = now inside, false = now outside
    $depth = 0;
    foreach($chars as $char)
    {
        if(in_array($char, $openers))
            $depth++;
        elseif(in_array($char, $closers))
            $depth--;
        elseif(in_array($char, $togglers))
        {
            if($toggle_states[$char])
                $depth--; // we are inside a toggle block, leave it and decrease the depth
            else
                // we are outside a toggle block, enter it and increase the depth
                $depth++;

            // invert the toggle block state
            $toggle_states[$char] = !$toggle_states[$char];
        }
        else
            $nextpart .= $char;

        if($depth < 0) $depth = 0;

        if(in_array($char, $delimiters) &&
           $depth == 0 &&
           !in_array($char, $closers))
        {
            $parts[] = substr($nextpart, 0, -1);
            $nextpart = "";
        }
    }
    if(strlen($nextpart) > 0)
        $parts[] = $nextpart;

    return $parts;
}

L'utilisation est comme suit. explode_adv prend 5 arguments:

  1. un tableau de caractères qui ouvrent un bloc - par exemple, [, (, etc.
  2. un tableau de caractères qui ferment un bloc - par exemple, ], ), etc.
  3. un tableau de caractères qui font alterner un bloc - par exemple, ", ', etc.
  4. un tableau de caractères qui devrait provoquer une scission dans la partie suivante.
  5. La chaîne à travailler.

Cette méthode a probablement des défauts - modifications sont les bienvenus

.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top