最稳妥方式是preg_match配合非贪婪匹配.*?,注意转义元字符、添加s/u修饰符处理换行和unicode,嵌套场景优先用专用解析器或计数器循环。

用 preg_match 提取两个固定字符之间的内容
最常用也最稳妥的方式是 preg_match 配合非贪婪匹配。比如从字符串 "start:hello world:end" 中提取 hello world,关键在模式里用 .*? 而不是 .*,否则会跨段匹配。
实操建议:
- 写法示例:
preg_match('/start:(.*?)end/', $str, $matches),结果在$matches[1] - 如果起止符本身是正则元字符(如
.、[、$),必须用preg_quote($char, '/')转义 - 注意默认不支持换行,若内容含换行符,需加
s修饰符:/start:(.*?)end/s - 避免写成
/(.*)/—— 它会从第一个起始符匹配到最后一个结束符,中间所有内容全吞掉
preg_match_all 提取多个相同结构的片段
当文本中有多个 【xxx】 或 [tag]content[/tag] 这类重复结构时,preg_match_all 是唯一合理选择。
实操建议:
- 示例:
preg_match_all('/\[(.*?)\]/', $text, $matches),内容在$matches[1]数组里 - 如果起始和结束标记不同(如 HTML 标签),推荐用命名捕获组提升可读性:
/'(.*?)/s' - 性能上,能用
strpos+substr简单拆分就别硬套正则——尤其当边界字符绝对唯一且无嵌套时
处理嵌套或不规则边界时别硬刚正则
PHP 的 PCRE 不支持真正的嵌套匹配(如 [[a[b]c]]),强行写递归模式((?R))容易失控,且 PHP 7.3+ 才稳定支持。
实操建议:
- 遇到括号嵌套、标签嵌套、引号包裹引号等场景,优先考虑专用解析器(如
DOMDocument解析 HTML,json_decode处理 JSON 片段) - 若必须手写,改用循环 + 计数器方式:逐字符扫描,遇左界
$depth++,遇右界$depth--,$depth === 0时截断 - 正则里用
(? 来跳过被反斜杠转义的左界,但要注意 PHP 字符串字面量本身也要双写反斜杠
中文标点或 Unicode 边界要显式声明 u 修饰符
用中文顿号、书名号、emoji 做边界时,preg_match 默认按字节匹配,会导致截断或漏匹配。
实操建议:
- 必须加
u修饰符:preg_match('/《(.*?)》/u', $str, $m) -
u会让.匹配任意 Unicode 字符(包括中文、emoji),否则它只认 ASCII - 如果起始符是 Unicode 字符且需转义,
preg_quote第二个参数要传'/',它会自动处理 Unicode 元字符 - 注意
u修饰符要求输入字符串本身是 UTF-8 编码,否则会直接返回 false
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











