匹配文本中的字面量方括号必须转义为\]和\],否则会被解析为字符类边界;正确提取[address:xxx]应使用/\[address:(.?)\]/,错误写法/[address:(.?)]/将导致语法或语义错误。

方括号 [] 在 PHP 正则中是字符类,不是字面量
很多人一看到文本里有 [Name:xxx] 就直接写 /[Name:(.*?)]/,结果完全不匹配——因为这里的 [ 和 ] 被正则引擎当作「字符类开始/结束」解析了,根本没当成普通方括号去匹配。
字符类 [abc] 表示“匹配 a、b 或 c 中任意一个”,[0-9] 表示“匹配任意数字”。它内部的 -、^、] 等都有特殊含义,比如 ] 必须放在开头才能表示字面量(如 []a-z]),而 [ 永远不能出现在字符类内部(除非被转义)。
所以:要匹配文本里的 [ 或 ],必须用反斜杠转义:\[ 和 \]。
匹配字面量方括号必须转义 \[ 和 \]
例如提取 [Address:Indonesia] 中的值,正确写法是:
preg_match('/\[Address:(.*?)\]/', $text, $matches);
错误写法(不转义):
preg_match('/[Address:(.*?)]/', $text, $matches); // ❌ 把 [Address: 当作字符类,语法错误或语义错乱
-
\[→ 匹配一个左方括号字符 -
(.*?)→ 非贪婪捕获,防止跨到下一个] -
\]→ 匹配一个右方括号字符(同样必须转义) - 若值内容可能含换行,加
s修饰符:/\[Address:(.*?)\]/s
想在字符类里写 ] 或 -?位置和转义很关键
字符类 [...] 是个特殊结构,里面的 ] 只有放在**开头**才被当作字面量;- 只有放在**开头或结尾**才被当作字面量,否则表示范围。
-
[]a-z]→ 合法,匹配]、a到z -
[a-z]→ 合法,匹配小写字母 -
[a\-z]→ 合法,匹配a、-、z -
[a-z-]→ 合法,同上,-在末尾是字面量 -
[a-z]和[z-a]不等价——后者是无效范围,PCRE 会报错 - 不要写
[^\]]来“匹配非右括号”,应写[^]](]放在开头后即可)
常见误用:把 [key:value] 当成结构,却忽略嵌套或非法格式
正则不是解析器。如果输入是用户可控的(比如表单提交、日志片段),preg_match() 很容易因格式异常失败或误匹配:
- 文本含未闭合的
[(如[Name:John [City:NYC)→ 正则可能跨太远或直接不匹配 - 值里本身含
](如[Note:see page 5])→.*?会在第一个]就停,截断为see page 5 - 多个相同字段(如两个
[Age:17])→preg_match()只取第一个,得用preg_match_all() - 字段名含空格或特殊字符(如
[Full Name:...])→ 正则得改成/\[Full Name:(.*?)\]/,但空格需显式处理
真正健壮的做法,是避免用正则解析非结构化标记;优先改用 parse_ini_string()、JSON 或自定义 tokenizer —— 正则只适合格式严格、来源可信的简单场景。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











