我正在尝试解析以这种格式构建的一行:
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);