将括号之间逗号分隔的文本解析为键值对数组



我正在尝试解析以这种格式构建的一行:

Files("textfile1.txt", 7268474425, "textfile2.txt", 661204928, "textfile3.txt", 121034)

我在C#中使用命名捕获组可以很好地实现这一点,但这是PHP,而且严格意义上。所以我不知道如何分离每个字段并构建一个可以迭代的关联数组。

我可以检索双引号中的第一个项目";textfile1.txt";使用

$string = 'Files("textfile1.txt", 7268474425, "textfile2.txt", 661204928, "textfile3.txt", 121034)';
preg_match("/(?:(?:"(?:\\"|[^"])+")|(?:'(?:\'|[^'])+'))/is", $string, $match);
print_r($match);
Array
(
[0] => 'textfile1.txt'
)

我想不通。我尝试了不同的表达式来同时考虑字符串/长字段,但没有成功。

我有什么东西不见了吗?

最终结果是将每个文件名/大小添加到一个数组中,以便以后访问。

感谢提供的任何帮助

https://regex101.com/r/naSdng/1

我的C#实现如下所示:

MatchCollection result = Regex.Matches(file, @"(?:G(?!A)s*,s*|w+()(?:""(?<filename>.*?)""|'(?<filename>.*?)')s*,s*(?<filesize>d+)");
matchCol = result;
foreach (Match match in result)
{
ListViewItem ItemArray = new(new string[] {
match.Groups["filename"].Value.Trim(), BytesToReadableString(Convert.ToInt64(match.Groups["filesize"].Value)), "Ready"
});
fileList.Items.Add(ItemArray);
}

您在C#中显示的正则表达式也可以很容易地适应PHP。

您可以使用:

(?:w+(h*|(?<!A)Gh*,h*)"(?<filename>[^"]+)"h*,h*(?<filesize>d+)

请注意,我对正则表达式进行了一些重构,使其更加高效。

RegEx演示

代码演示

代码:

<?php
$s = 'Files("textfile1.txt", 7268474425, "textfile2.txt", 661204928, "textfile3.txt", 121034)';
if (preg_match_all('/(?:w+(h*|(?<!A)Gh*,h*)"(?<filename>[^"]+)"h*,h*(?<filesize>d+)/', $s, $m)) {
$out = array_combine ( $m['filename'], $m['filesize'] );
print_r($out);
}
?>

输出:

Array
(
[textfile1.txt] => 7268474425
[textfile2.txt] => 661204928
[textfile3.txt] => 121034
)

RegEx详细信息:

  • (?::启动非捕获组
    • w+(h*:匹配后面跟有(的1个以上单词字符和0个或多个空格
    • |:或
    • (?<!A)G:从上一次匹配结束时开始匹配
    • h*,h*:匹配用0个或多个空格包围的逗号
  • ):结束非捕获组
  • "(?<filename>[^"]+)":将双引号字符串与命名捕获组filename匹配,以匹配任何非"的字符的1+
  • h*,h*:匹配包含0个或多个空格的逗号
  • (?<filesize>d+):命名捕获组filesize以匹配1位以上数字

将输入字符串转换为有效的json字符串并对其进行解码,以确保将数值强制转换为整数。将平面数组分块成对,并将每对作为关联元素分配给结果数组。

代码:(演示(

var_export(
array_reduce(
array_chunk(
json_decode('[' . substr($string, 6, -1) . ']'),
2
),
function ($result, $row) {
$result[$row[0]] = $row[1];
return $result;
}
)
);

或者每隔一秒在逗号空间上拆分内部文本,并用CCD_ 14解析逗号分隔的字符串。

代码:(演示(

var_export(
array_reduce(
preg_split('/[^,]+,[^,]+K, /', substr($string, 6, -1)),
function ($result, $string) {
[$key, $result[$key]] = sscanf($string, '"%[^"]", %d');
return $result;
}
)
);

或者将preg_match_all()G(连续元字符(一起使用,然后将结果配对到foreach()中,这样您就可以将数字显式转换为int类型值。

代码:(演示(

$result = [];
preg_match_all('/(?:^w+(|G, )"([^"]+)", (d+)/', $string, $matches, PREG_SET_ORDER);
foreach ($matches as [1 => $key, 2 => $val]) {
$result[$key] = (int) $val;
}
var_export($result);

或者在分解括号内的内容后对每个单独的值进行迭代。然后切换给定字符串的用法以确定键和值。

代码:(演示(

$result = [];
foreach (explode(', ', substr($string, 6, -1)) as $val) {
if (!isset($key)) {
$key = trim($val, '"');
} else {
$result[$key] = (int) $val;
unset($key);
}
}
var_export($result);

最新更新