PHP中使用正则匹配{list:start/end}花括号标签间内容返回空数组的问题
解决preg_match_all匹配list标签返回空数组的问题
首先,你的正则表达式有两个关键问题导致匹配失败:
- 默认不匹配换行符:正则里的
.元字符默认不会匹配换行符,如果你的目标内容中包含换行(哪怕示例里是单行,实际场景可能存在),就会导致中间的(.*?)无法匹配完整内容。 - 未限制start/end标识一致:原正则允许
{list:start:X}和{list:end:Y}这种不对应的配对,这可能不是你想要的逻辑,也可能在复杂内容中导致匹配混乱。
修正后的正则与代码
给正则添加s修饰符(开启DOTALL模式,让.匹配包括换行在内的所有字符),同时用反向引用\1保证start和end的标识完全一致:
$HTML = '{list:start:Data} {id} is having a title of {title} {list:end:Data}'; // 修正后的正则:添加s修饰符,用\1关联start和end的标识 preg_match_all('/\{list:start:(.*?)\}(.*?)\{list:end:\1\}/s', $HTML, $match); // 整理成你期望的数组格式 $formattedMatch = []; if (!empty($match[1]) && !empty($match[2])) { foreach ($match[1] as $idx => $tagName) { $formattedMatch[] = [ 'string' => $tagName, 'value' => trim($match[2][$idx]) // 可选:trim去除内容前后的空格 ]; } } print_r($formattedMatch);
运行结果
这段代码会输出你期望的结构:
Array ( [0] => Array ( [string] => Data [value] => {id} is having a title of {title} ) )
额外说明
- 如果你的内容中存在多个独立的list块(比如
{list:start:Data1}...{list:end:Data1}{list:start:Data2}...{list:end:Data2}),这个正则也能正确匹配每一对,返回对应的多组结果。 - 如果内容里有嵌套的
{...}结构,这个简单的非贪婪匹配可能会失效,此时需要更复杂的正则或者用解析器来处理,但针对你描述的场景,这个方案完全够用。
内容的提问来源于stack exchange,提问作者Clipso
相关产品推荐
相关产品推荐

