如何从字符串中提取数字并添加到数组中?

时间:2019-05-26 16:26:49

标签: php regex split preg-match-all regex-lookarounds

我要转换此字符串:

<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 个答案:

答案 0 :(得分:4)

只要您的输出在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
)

答案 1 :(得分:3)

<?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 :(得分:2)

如果要将开始标签中的数字与结束标签中的数字进行匹配,则可以使用正则表达式对第一个捕获组使用backreference

<div v-show="isLoading">Loading...</div>
<v-baller-chart v-if="isDataLoaded" :data="chartData"></v-baller-chart>
<button v-show="isDataFailed" type="button" @click="handleGetChart">TRY AGAIN</button>

说明

  • <(\d+)>\h*\d+(?:\.\d+)?\h*</\h*\1> 匹配<字符
  • >在组1中捕获匹配1个以上的数字并匹配(\d+)>
  • >匹配0+个水平空格字符
  • \h*匹配1位以上的数字,后跟可选部分以匹配点和1位以上的数字
  • \d+(?:\.\d+)?匹配0+个水平空格字符
  • \h*匹配<
  • <匹配/\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]));

请注意,现在阵列键为5、7和8。请记住,如果您可能使用不同的数据,则该阵列不能有重复的键。

答案 3 :(得分:1)

在这里,我们还可以使用正则表达式并收集所需的数字,然后将其推入新数组:

## UV SNAPSHOTS
## PYTHON
import maya.cmds as mc


def get_snapshot_res(label, *args):
    uv_snap_res = label

def save_snapshots(get_snapshot_res, uv_snap_res, *args):
    get_snapshot_res(uv_snap_res)
    print get_snapshot_res

def passValue(texSizeControl, *args):
    radioCol = mc.radioCollection(texSizeControl, query=True, sl=True)
    getSelectRadioVal = mc.radioButton(radioCol, query=True, label=True)
    get_snapshot_res(getSelectRadioVal)

def save_snapshots_ui(*args):
    myWindow = 'Create UV Snapshots'
    if mc.window(myWindow, exists=True):
        mc.deleteUI(myWindow)
    mc.window(myWindow, title = myWindow)
    mc.columnLayout(adjustableColumn=True)
    mc.text(label='Choose your resolution for UV Snapshots', font='obliqueLabelFont')
    texSizeControl = mc.radioCollection()
    saveRadio1k = mc.radioButton(label='1024')
    saveRadio2k = mc.radioButton(label='2048')
    saveRadio4k = mc.radioButton(label='4096')
    saveRadio8k = mc.radioButton(label='8192')
    texSizeControl = mc.radioCollection(texSizeControl, edit=True, select=saveRadio2k )
    mc.button(label='save', command= partial(passValue, save_snapshots, texSizeControl))
    mc.setParent( '..' )
    mc.showWindow()

save_snapshots_ui()

此表达式也可以与nested elements一起使用。

测试

(?:<)(\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);

DEMO

RegEx电路

jex.im可视化正则表达式:

enter image description here