Как извлечь числа из строки и добавить в массив? - PullRequest
2 голосов
/ 26 мая 2019

Я хочу преобразовать эту строку:

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

в массив со значением ключа

Я был бы очень признателен за помощь

Я пробовал разные стратегии xmlParse, но этоне совсем xml.

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

Ответ: Строка не может быть проанализирована как XML

Я ожидаю массив, подобный этому:

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

Ответы [ 4 ]

4 голосов
/ 26 мая 2019

Пока в выводе есть цифры в начале имени тега XML, он не будет действительным XML.Возможно, вам придется прибегнуть к использованию регулярного выражения для выполнения этой работы.

При этом используется <(\d*)>(.*?)</~, который ищет < с последующими цифрами, затем > и захватывает все до следующего </.Затем он объединяет значения из группы захвата 1 (имя тега) и 2 (значение) ...

$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);

дает ...

Array
(
    [5] => 20825.24
    [7] => 0.0
    [8] => 0.0
)
3 голосов
/ 26 мая 2019
<?php

$subject = '<5> 20825.24 <7> 0.0 <8> 0.0';
$pattern = '/\<(\d)\>\s+(\d+\.\d+)/u';
$result = preg_match_all($pattern,$subject,$output);

$numbers = $output[1];
$output = $output[2];
$outTotal = [];

foreach ($numbers as $key => $number) {
    $outTotal[$number] = $output[$key];
}
var_dump($outTotal);

дает:

array(3) {
  [5]=>
  string(8) "20825.24"
  [7]=>
  string(3) "0.0"
  [8]=>
  string(3) "0.0"
}
2 голосов
/ 26 мая 2019

Если вы хотите сопоставить цифры в открывающем теге с цифрами в закрывающем теге, вы можете использовать регулярное выражение, используя обратную ссылку к первой группе захвата:

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

Объяснение

  • < Совпадение > символ
  • (\d+)> Захват в группе 1 соответствующих 1+ цифр и совпадений >
  • \h* Матч 0+ горизонтальных пробелов
  • \d+(?:\.\d+)? Совпадение цифр 1+, за которыми следует дополнительная часть для совпадения с точкой и цифрами 1+
  • \h* Матч 0+ горизонтальных пробелов
  • < Совпадение <
  • /\h* Совпадение \, за которым следуют 0+ горизонтальных пробелов
  • \1> Сопоставить обратную ссылку с группой 1, используя \1 и сопоставить >

Regex demo | Php demo

Например:

$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]));

Результат

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

Обратите внимание, что теперь ключами массива являются 5, 7 и 8. Имейте в виду, что, если вы можете использовать разные данные, эти массивы не могут иметь дублирующиеся ключи.

1 голос
/ 26 мая 2019

Здесь мы также можем использовать регулярное выражение и собирать нужные нам числа, а затем помещать его в новый массив:

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

Это выражение также может работать с вложенными элементами .

Тест

$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);

выход

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

DEMO

RegEx Circuit

jex.im визуализирует регулярные выражения:

enter image description here

...