php 将括号子字符串从一个数组Map到另一个数组,并在没有括号子字符串时使用回退字符串

1bqhqjot  于 2023-03-07  发布在  PHP
关注(0)|答案(5)|浏览(127)

修改查询结果后,我得到了一个如下所示的数组:

[0] => foo (bar1)
[1] => bar (foo2)
[2] => bas
[3] => foo (bas3)
[4] => bar

如您所见,有些值包含括号,有些则没有。
我需要一个自己的(新的)数组中每个值的括号部分,键应该保留,如果第一个数组的值中没有括号,第二个数组中的值应该是 ,两个数组中的数组键应该相同,因此第二个数组应该如下所示:

[0] => (bar1)
[1] => (foo2)
[2] => 
[3] => (bas3)
[4] =>

到目前为止,我得到了这个PHP代码:

$pattern = "/\((.*?)\)/";  //Looks for text in parentheses
$array1 = <see above>
$array2 = array();     //The second array, which should contain the extracted parentheses parts
foreach($array1 as $index => $value) {
  $array2 = preg_grep($pattern,$array1);
}

这很好用,但是当找到圆括号时,它将$array1的整个值显示为$array2中的值,$array1中没有圆括号的值完全丢失。(...)-part,如果没有检测到括号,从$array1中删除它,并将&nbsp;添加到$array2。我尝试使用preg_match来实现这一点,但这给了我一个数组到字符串的转换错误。
有人知道如何解决这个问题吗?

hlswsv35

hlswsv351#

使用array_walk()的变体:

<?php
$input = [
  0 => "foo (bar1)",
  1 => "bar (foo2)",
  2 => "bas",
  3 => "foo (bas3)",
  4 => "bar",
];

$output = [];
array_walk($input, function($entry, $key) use (&$output) {
  $output[$key] = preg_match('|\([^\)]*\)|', $entry, $token) ? $token[0] : "&nbsp;";
});

print_r($output);

输出显然是:

Array
(
    [0] => (bar1)
    [1] => (foo2)
    [2] => &nbsp;
    [3] => (bas3)
    [4] => &nbsp;
)
ef1yzkbh

ef1yzkbh2#

使用foreach和格式化字符串:

$arr = ['foo (bar1)', 'bar (foo2)', 'bas', 'foo (bas3)', 'bar'];
$res = [];

foreach($arr as $k => $v) {
    sscanf($v, '%[^ (] %s', $arr[$k], $res[$k]);
    $res[$k] = $res[$k] ?? ''; // or '&nbsp;'
}

print_r($arr);
print_r($res);
iyzzxitl

iyzzxitl3#

您可以对每个元素使用正则表达式。
这将找到一个左括号。后面跟着任何字符,直到一个右括号。当找到时,第一个匹配将返回&nbsp;

print_r(array_map(
    fn($item) => preg_match('/(\(.*?\))/', $item, $matches) ? $matches[1] : '&nbsp;', 
    ['foo (bar1)', 'bar (foo2)', 'bas', 'foo (bas3)', 'bar']
));
Array
(
    [0] => (bar1)
    [1] => (foo2)
    [2] => &nbsp;
    [3] => (bas3)
    [4] => &nbsp;
)
omtl5h9j

omtl5h9j4#

我认为最简单的是,这个任务适合迭代调用strstr()strpbrk()具有与字符掩码相同的功能),如果找不到所需的左括号,则回退到&nbsp;
代码:(Demo

var_export(
    array_map(fn($v) => strstr($v, '(') ?: '&nbsp;', $array)
);

与Casimir的sscanf()解决方案不同,我更喜欢使用array_map(),并在解析(using *)时忽略括号前的子字符串。
在尝试解析每个字符串时,该函数将返回一个包含null或括号值的单元素数组。如果null返回到所需的&nbsp;字符串。
在解析模式中,%*[^(]表示匹配但不保留字符串开头到第一个左括号之间的字符。然后%s将匹配并保留所有后续的非空白字符。保留的括号子字符串可以作为sscanf()返回数组中的第一个元素访问。
代码:(Demo

var_export(
    array_map(fn($v) => sscanf($v, '%*[^(]%s')[0] ?? '&nbsp;', $array)
);

它的正则表达式版本是:(Demo

var_export(
    array_map(fn($v) => preg_replace('/[^(]*(.*)/', '$1', $v) ?: '&nbsp;', $array)
);

或者使用preg_match():(一对四对一对)

var_export(
    array_map(fn($v) => preg_match('/\(.+\)/', $v, $m) ? $m[0] : '&nbsp;', $array)
);
bcs8qyzn

bcs8qyzn5#

这可能会有帮助

$pattern = "/\((.*?)\)/";  
$array1 = [];
$array2 = array();  
foreach ($array1 as $index => $value) {
    preg_match($pattern, $value, $matches);  
    if (isset($matches[1])) {
        $array2[$index] = str_replace($matches[0], "", $value); 
    } else {
        $array2[$index] = $value;  
    }
}
print_r($array2);

相关问题