根据正则表达式替换数组中的数据
Posted
技术标签:
【中文标题】根据正则表达式替换数组中的数据【英文标题】:Replace data in array based on regex 【发布时间】:2020-07-01 13:50:20 【问题描述】:我有下一个包含数据的数组(它是动态生成的)。 现在我想做一些魔术并调整数组。
array(1)
["table"]=>
array(3)
["header"]=>
array(4)
[0]=>
array(1)
["c"]=>
string(4) "Naam"
[1]=>
array(1)
["c"]=>
string(7) "Functie"
[2]=>
array(1)
["c"]=>
string(13) "Nevenfuncties"
[3]=>
array(1)
["c"]=>
string(34) " commissies"
["caption"]=>
bool(false)
["body"]=>
array(3)
[0]=>
array(4)
[0]=>
array(1)
["c"]=>
string(16) "*|class:orange|*"
[1]=>
array(1)
["c"]=>
string(6) "dsasad"
[2]=>
array(1)
["c"]=>
string(0) ""
[3]=>
array(1)
["c"]=>
string(0) ""
[1]=>
array(4)
[0]=>
array(1)
["c"]=>
string(4) "brrr"
[1]=>
array(1)
["c"]=>
string(6) "adsdsa"
[2]=>
array(1)
["c"]=>
string(0) ""
[3]=>
array(1)
["c"]=>
string(0) ""
[2]=>
array(4)
[0]=>
array(1)
["c"]=>
string(6) "dsasad"
[1]=>
array(1)
["c"]=>
string(6) "dsadas"
[2]=>
array(1)
["c"]=>
string(4) "dsad"
[3]=>
array(1)
["c"]=>
string(0) ""
当我们查看 ['header'] 时,它包含 ['c'](单元格数据)。这可以是文本,也可以是标签。
例如:*|class:orange|* here some text
。
现在我想将它们拆分并覆盖 ['c'] 如果它包含 '|class:orange|'。 所以当你有这个时:
array(1)
["c"]=>
string(7) "*|class:orange|* hello"
会变成这样:
array(2)
["c"]=>
string(7) "hello",
["class"]=>
string(7) "orange",
这样我可以拆分类并将其添加到数组中。但我被困在 preg_match 上。
foreach ($table as &$row)
foreach ($row['header'] as &$header)
// $header['class'] = 123;
preg_match('/\*\|class:([^\|])\|\*/', $header['c'], $matches);
我需要做两件事
向数组 ($header['class']) 添加一个属性,类位于 class:example 之后。 我需要替换 $header['c'] 使其不包含*|class:orange|*
并且仅包含其余文本。
【问题讨论】:
模式可以是这样的\*\|class:([^\|]+)\|\*\h*(.+)
得到2个捕获组regex101.com/r/NvEU5M/1
谢谢,我已经在\*\|class:([^\|]+)\|\*\h*(.*)
修改了,所以不需要空格
不客气,我已将其添加为答案的更新。
【参考方案1】:
不需要正则表达式(还)。可以通过分隔符定位找到标签:
foreach ($row['header'] as &$header)
$str = $header['c'];
$tagged = substr($str, 0, 2) === '*|' && $pos = strpos($str, '|* ');
if (!$tagged) continue;
[$tag, $value] = explode(':', substr($str, 2, $pos - 2));
$header['c'] = substr($str, $pos + 3);
$header[$tag] = $value;
【讨论】:
【参考方案2】:例如,您可以使用 2 个捕获组并将它们用作 c 和新类键的值。
对于第二个捕获组,您可以确保使用 \S
匹配至少一个非空白字符
注意重复字符类 1 次或更多次,并且不必转义字符类中的管道。
\*\|class:([^|]+)\|\*\h*(\S.*)
或者如果第 2 组后面的内容可以是可选的:
\*\|class:([^\|]+)\|\*\h*(.*)
Regex demo
解释第一模式
\*\|
匹配*|
class:
字面匹配
([^|]+)
捕获组 1,匹配除 |
之外的任何字符 1+ 次
\|\*\h*
匹配 |*
后跟 0+ 个水平空白字符
(\S.*)
捕获组 2,匹配一个非空白字符和 0+ 次除换行符以外的任何字符
Regex demo | php demo
示例代码
$array = [
"c" => "*|class:orange|* hello"
];
$pattern = "~\*\|class:([^|]+)\|\*\h*(\S.*)~";
foreach ($array as $key => $string)
if (preg_match($pattern, $string, $matches))
$array[$key] = $matches[2];
$array["class"] = $matches[1];
print_r($array);
输出
Array
(
[c] => hello
[class] => orange
)
【讨论】:
以上是关于根据正则表达式替换数组中的数据的主要内容,如果未能解决你的问题,请参考以下文章
js正则匹配替代指定字符(根据img标签的src中的命名规则,用正则表达式替换成下面格式的文字)