解析包含 3 个分隔符的格式化字符串以创建多个平面数组



我有以下格式的字符串:

$strings[1] = cat:others;id:4,9,13
$strings[2] = id:4,9,13;cat:electric-products
$strings[3] = id:4,9,13;cat:foods;
$strings[4] = cat:drinks,foods;

其中cat表示类别,id表示产品的标识号。

我想拆分这些字符串并转换为数组$cats = array('others');$ids = array('4','9','13');

我知道它可以通过多个步骤通过foreach和爆炸功能来完成。我想我在附近的某个地方,但以下代码不起作用。

另外,我想知道是否可以通过preg_matchpreg_split更少的步骤来完成。或任何其他更简单的方法。

foreach ($strings as $key=>$string) {
$temps = explode(';', $string);
foreach($temps as $temp) {
$tempnest = explode(':', $temp);
$array[$tempnest[0]] .= explode(',', $tempnest[1]);
}
}

我想要的结果应该是:

$cats = ['others', 'electric-products', 'foods', 'drinks';

$ids = ['4','9','13'];

一种选择是对爆炸后的第一项进行字符串比较,catid将值设置为正确的数组。

$strings = ["cat:others;id:4,9,13", "id:4,9,13;cat:electric-products", "id:4,9,13;cat:foods", "cat:drinks,foods"];
foreach ($strings as $key=>$string) {
$temps = explode(';', $string);
$cats = [];
$ids = [];
foreach ($temps as $temp) {
$tempnest = explode(':', $temp);
if ($tempnest[0] === "cat") {
$cats = explode(',', $tempnest[1]);
}
if ($tempnest[0] === "id") {
$ids = explode(',', $tempnest[1]);
}
}
print_r($cats);
print_r($ids);
}

Php 演示

例如,第一项的输出如下所示

Array
(
[0] => others
)
Array
(
[0] => 4
[1] => 9
[2] => 13
)

如果要聚合 2 个数组中的所有值,可以array_merge结果,最后使用 array_unique 获取唯一值。

$strings = ["cat:others;id:4,9,13", "id:4,9,13;cat:electric-products", "id:4,9,13;cat:foods", "cat:drinks,foods"];
$cats = [];
$ids = [];
foreach ($strings as $key=>$string) {
$temps = explode(';', $string);
foreach ($temps as $temp) {
$tempnest = explode(':', $temp);
if ($tempnest[0] === "cat") {
$cats = array_merge(explode(',', $tempnest[1]), $cats);
}
if ($tempnest[0] === "id") {
$ids = array_merge(explode(',', $tempnest[1]), $ids);
}
}
}
print_r(array_unique($cats));
print_r(array_unique($ids));

输出

Array
(
[0] => drinks
[1] => foods
[3] => electric-products
[4] => others
)
Array
(
[0] => 4
[1] => 9
[2] => 13
)

Php 演示

我通常不建议使用变量,但您正在寻找一个使用正则表达式以避免多次explode()调用的时尚片段。

下面是一个不使用explode()调用和嵌套foreach()循环的脚本。

您可以通过调用var_export($matches);来查看G("continue"元字符)如何允许相对于"存储桶"标签(idcat)进行连续匹配。

如果这是我自己的代码,我可能不会创建单独的变量,而是创建一个包含id的数组,cat---这将减轻对变量的需求。

通过使用遇到的值作为要添加到存储桶的元素的键,您可以确保任何存储桶中没有重复值 - 如果要重新索引存储桶元素,只需调用array_values()即可。

代码: (演示) (正则表达式101)

$count = preg_match_all(
'/(?:^|;)(id|cat):|G(?!^),?([^,;]+)/',
implode(';', $strings),
$matches,
PREG_UNMATCHED_AS_NULL
);
$cat = [];
$id = [];
for ($i = 0; $i < $count; ++$i) {
if ($matches[1][$i] !== null) {
$arrayName = $matches[1][$i];
} else {
${$arrayName}[$matches[2][$i]] = $matches[2][$i];
}
}
var_export(array_values($id));
echo "n---n";
var_export(array_values($cat));

综上所述,我可能不会依赖正则表达式,因为它对于新手正则表达式开发人员来说不是很好读。 所需的逻辑要简单得多,并且更容易使用嵌套循环和爆炸进行维护。 这是我对您的代码的调整。

代码:(演示)

$result = ['id' => [], 'cat' => []];
foreach ($strings as $string) {
foreach (explode(';', $string) as $segment) {
[$key, $values] = explode(':', $segment, 2);
array_push($result[$key], ...explode(',', $values));
}
}
var_export(array_unique($result['id']));
echo "n---n";
var_export(array_unique($result['cat']));

附言:您发布的编码尝试是使用组合运算符.=(赋值和连接),而不是更合适的组合运算符+=(赋值和数组联合)。

最新更新