You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP正则:如何基于[:graph:]排除黑名单并扩展白名单字符?

问题分析与解决方案

你的代码问题主要出在正则模式的构建上,同时没考虑白名单的处理逻辑,以下是具体修正方案:

核心问题点

  1. 正则语法错误:你写的[{".preg_quote($blacklist, '')."}]+会把{和}当作字面量字符匹配,导致额外删除这两个符号,正确的写法应该是直接用[{$escaped_blacklist}]+`来匹配黑名单内的字符。
  2. 白名单未处理:原代码会移除所有非[:graph:]的字符,包括你想保留的白名单字符(比如空格),需要把白名单加入到「不被移除」的集合中。

修正后的完整代码

// 示例参数,可根据实际需求修改
$length = 12;
$blacklist = '~`'; // 需要排除的字符
$whitelist = ' '; // 需要额外允许的字符(如空格)

// 转义特殊字符,适配正则语法
$escaped_blacklist = preg_quote($blacklist, '`');
$escaped_whitelist = preg_quote($whitelist, '`');

// 构建正则模式
if (empty($blacklist) && empty($whitelist)) {
    // 基础场景:仅保留[:graph:]字符
    $pattern = '`[^[:graph:]]+`s';
} elseif (empty($blacklist)) {
    // 仅添加白名单:保留[:graph:] + 白名单字符
    $pattern = "`[^[:graph:]{$escaped_whitelist}]+`s";
} elseif (empty($whitelist)) {
    // 仅排除黑名单:保留[:graph:] 减去 黑名单字符
    $pattern = "`(?:[^[:graph:]]+|[{$escaped_blacklist}]+)`s";
} else {
    // 同时处理黑名单和白名单:保留[:graph:]减黑名单 + 白名单,删除其余字符
    $pattern = "`(?:[^[:graph:]{$escaped_whitelist}]+|[{$escaped_blacklist}]+)`s";
}

// 生成符合要求的随机字符串
$secure_password = substr(preg_replace($pattern, "", random_bytes($length * 10)), 0, $length);

代码说明

  • 字符转义:用preg_quote处理黑名单和白名单字符,避免正则特殊字符(如^、-、])破坏语法结构,第二个参数指定正则分隔符`,确保分隔符本身被正确转义。
  • 模式逻辑:
    • 当无黑名单和白名单时,沿用你原本的基础模式。
    • 仅加白名单时,修改否定字符组为[^[:graph:]{$escaped_whitelist}],确保白名单字符不被移除。
    • 仅排除黑名单时,用(?:[^[:graph:]]+|[{$escaped_blacklist}]+)匹配「非[:graph:]字符」或「黑名单字符」,统一替换为空。
    • 同时处理两者时,合并上述逻辑,确保最终只保留你需要的字符集合。

内容的提问来源于stack exchange,提问作者carlo-849978

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 03:24:55