Comment puis-je 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")
Pour que le texte entre guillemets soit 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 en un tableau. Comment puis-je faire des mots entre guillemets traités comme un seul mot?
Vous pouvez utiliser une 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 les guillemets échappés à l'intérieur des chaînes entre guillemets.
MODIFIER
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 de correspondance %22
au lieu de guillemets doubles, vous feriez:
preg_match_all('/%22(?:\\\\.|(?!%22).)*%22|\S+/', $text, $matches);
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 d'éclatement multiple
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);
Je suis venu ici avec un problème de division de chaîne complexe similaire à celui-ci, mais aucune des réponses ici n'a fait exactement ce que je voulais - j'ai donc écrit la mienne.
Je le poste ici juste au cas où il serait utile à quelqu'un d'autre.
C'est probablement une façon très lente et inefficace de le faire - mais cela fonctionne 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 la suivante. explode_adv
prend 5 arguments:
[
, (
, etc.]
, )
, etc."
, '
, etc.Cette méthode a probablement des défauts - les modifications sont les bienvenues.
Dans certaines situations, le peu connu token_get_all()
peut s'avérer 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
)