
本文介绍一种正则表达式方案,用于从杂乱文本中仅保留井号(#)、换行符,以及包含至少一个数字的完整括号结构(圆括号()、方括号[]、花括号{}),其余所有字符(包括空格、字母、标点等)一律清除。
本文介绍一种正则表达式方案,用于从杂乱文本中仅保留井号(#)、换行符,以及包含至少一个数字的完整括号结构(圆括号()、方括号[]、花括号{}),其余所有字符(包括空格、字母、标点等)一律清除。
在数据清洗或日志预处理场景中,常需从半结构化文本中提取关键标记——例如以 # 开头的行标识、含数字的括号组(如 (1296)、{20}、[529]),而彻底剔除干扰内容(如 (MONDAY )、[20 Mtrs]、{ 03 Foot } 等不含纯数字或含多余空格/字母的无效括号)。原始尝试使用 (*SKIP)(*F) 的正则未能正确处理空白和边界,导致残留无效字符或括号截断。
正确的解决方案是:优先匹配「合法数字括号」并跳过((*SKIP)(*F)),再统一删除其余非关键字符。以下是推荐正则表达式:
$re = '/(?:\[\h*\d[\h\d]*]|\(\h*\d[\h\d]*\)|{\h*\d[\h\d]*})\h*(*SKIP)(*F)|[^#\n]/m';
$result = preg_replace($re, '', $input);✅ 关键设计解析:
-
(?:(...)|(...)|(...))\h*(*SKIP)(*F):非捕获组内定义三类合法模式:-
\[\h*\d[\h\d]*]→ 匹配[+ 零或多个水平空白 + 至少一个数字 + 零或多个数字/空白 +] -
\(\h*\d[\h\d]*\)→ 同理匹配(1296)、( 7 )等含数字的圆括号(允许内部空格) -
{\h*\d[\h\d]*}→ 同理匹配{20}、{ 03 }等花括号
-
-
\h*在组后额外匹配后续空白(如{20}中的尾随空格),确保其一并被跳过,避免残留空格破坏格式。 -
|[^#\n]:对未被跳过的所有字符,只要不是#或换行符,全部删除。
⚠️ 注意事项:
- 该正则不保留括号间的原始空格(如
{20} [529]中的空格会被保留,因它位于两个已跳过的合法结构之间;但({20})中的括号外空格若未被覆盖,可能残留——实际测试表明本模式已稳健处理常见间隔); -
\h(horizontal whitespace)比\s更安全,避免误吞换行符,确保#和换行始终被保留; - 若需严格保留“括号间单个空格”,可在替换后追加
preg_replace('/\s+/', ' ', $result)去重空白,但本需求示例输出中空格已自然保留,无需额外处理; - 不支持嵌套括号(如
(A (123))),但原始样本无此情况,且该需求本身聚焦于扁平括号结构。
运行上述代码,输入示例将精确输出:
#(1296) {20} [529] [1496] [411]
#(1296)
#(646) {20}
#{19} [455] [721] (1296) [2741] {20}
#{19} (1296)该方案兼顾准确性与可维护性,适用于 PHP 的 preg_replace,亦可轻松适配其他支持 (*SKIP)(*F) 的引擎(如 PCRE2)。

















