2
votes

Comment extraire des nombres d'une chaîne et les ajouter à un tableau?

Je veux convertir cette chaîne:

[5=>20825.24,7=>0.0,8=>0.0]

en un tableau avec une valeur de clé

J'apprécierais vraiment l'aide

J'ai essayé différents xmlParse mais ce n'est pas exactement un xml.

$xml = new \SimpleXMLElement("<5>20825.24</5><7>0.0</ 7><8>0.0</8>");

Réponse: La chaîne n'a pas pu être analysée comme XML

J'attends un tableau comme celui-ci: p>

<5> 20825.24 </ 5> <7> 0.0 </ 7> <8> 0.0 </ 8>


1 commentaires

Les noms de balises XML ne peuvent pas commencer par un nombre, donc cela signifie que si vous ne traitez pas les données - ce n'est pas du XML valide (il n'a pas non plus de nœud racine - mais c'est facilement corrigé)


4 Réponses :


2
votes
array(3) {
  [5]=>
  string(8) "20825.24"
  [7]=>
  string(3) "0.0"
  [8]=>
  string(3) "0.0"
}

0 commentaires

3
votes

Tant que votre sortie contient des nombres au début du nom de la balise XML, ce ne sera pas du XML valide. Vous devrez peut-être recourir à une expression régulière pour faire le travail.

Cela utilise (. *?) ~ qui recherche un suivi de chiffres, puis du > et capture tout jusqu'au prochain . Il combine ensuite les valeurs du groupe de capture 1 (le nom de la balise) et 2 (la valeur) ...

Array
(
    [5] => 20825.24
    [7] => 0.0
    [8] => 0.0
)

donne ...

$data = "<5>20825.24</5><7>0.0</ 7><8>0.0</8>";

preg_match_all("~<(\d*)>(.*?)</~", $data, $matches);
$output = array_combine($matches[1], $matches[2]);
print_r($output);


1 commentaires

C'est concis et beaucoup plus propre que mes ans.



1
votes

Ici, nous pouvons également utiliser une expression régulière et collecter les nombres souhaités, puis les pousser dans un nouveau tableau:

array(3) {
  [5]=>
  string(8) "20825.24"
  [7]=>
  string(3) "0.0"
  [8]=>
  string(3) "0.0"
}

Cette expression peut également fonctionner avec éléments imbriqués .

Test

$re = '/(?:<)(\d?)(?:>)(?:.+?)([0-9.]+)?/m';
$str = '<5> 20825.24 </ 5> <7> 0.0 </ 7> <8> 0.0 </ 8>';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

$arr = array();
foreach ($matches as $key => $value) {
    $arr[$value[1]] = $value[2];
}

var_dump($arr);

Sortie

(?:<)(\d?)(?:>)(?:.+?)([0-9.]+)?

DEMO

Circuit RegEx

jex.im visualise les expressions régulières:

entrer l'image description ici


0 commentaires

1
votes

Si vous voulez faire correspondre les chiffres de la balise d'ouverture avec les chiffres de la balise de fermeture, vous pouvez utiliser une expression régulière en utilisant backreference au premier groupe de capture:

Array
(
    [5] => 20825.24
    [7] => 0.0
    [8] => 0.0
)

Explication

  • Match > char
  • (\d+)> Capture dans le groupe 1 correspondant à 1+ chiffres et correspond à >
  • \ h * Correspond à 0+ caractères d'espacement horizontal
  • \ d + (?: \. \ d +)? Faire correspondre 1+ chiffres suivis d'une partie facultative pour faire correspondre un point et 1+ chiffres
  • \ h * Correspond à 0+ caractères d'espacement horizontal
  • Correspondance
  • / \ h * Faire correspondre \ suivi de plus de 0 caractères d'espaces blancs horizontaux
  • \1> Faire correspondre la référence arrière au groupe 1 en utilisant \ 1 et faire correspondre >

Démo Regex | Démo Php

Par exemple:

$re = '~<(\d+)>\h*(\d+(?:\.\d+)?)\h*</\h*\1>~m';
$str = '<5> 20825.24 </ 5> <7> 0.0 </ 7> <8> 0.0 </ 8>';
preg_match_all($re, $str, $matches);
print_r(array_combine($matches[1], $matches[2]));

Résultat

<(\d+)>\h*\d+(?:\.\d+)?\h*</\h*\1>

Notez que maintenant les clés de tableau sont 5, 7 et 8. Gardez à l'esprit que si vous pouvez utiliser des données différentes, ces tableaux ne peuvent pas avoir de clés en double .


0 commentaires