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

如何匹配UTF8编码的ZWSP(零宽空格)?是否存在Bug?

匹配/替换UTF-8编码的零宽空格(ZWSP)问题

ZWSP编码说明:

ZWSP: \x20\x0B
ZWSP (UTF-8): \xE2\x80\x8B

我额外测试了非断空格(NBSP),表现符合预期。所有preg_replace均使用UTF-8模式/u,测试情况如下:

  • 匹配NBSP正常:UTF-8编码输入被替换为空,输出为空字符串。
  • 匹配ZWSP时,仅输入为非UTF-8编码时有效。
  • 将ZWSP正则模式改为UTF-8编码版本,同时输入为UTF-8编码时,依然无法匹配。

核心问题

如何匹配UTF-8编码的ZWSP?或者这是一个Bug?

测试代码

$nbsp       = '\xA0'; // 非断空格
$zwsp       = '\x20\x0B'; // 零宽空格
$zwsp_utf8  = '\xE2\x80\x8B';

$input_nbsp_utf8    = "\xC2\xA0";
$input_zwsp         = "\x20\x0B";
$input_zwsp_utf8    = "\xE2\x80\x8B";

// NBSP测试
echo "NBSP\n-----\n";
echo "in: $input_nbsp_utf8--\nhex: ".bin2hex($input_nbsp_utf8)."\n";
$output = preg_replace('/'.$nbsp.'/u', '', $input_nbsp_utf8);
echo "out: $output--\nhex: ".bin2hex($output)."\n\n";

// ZWSP测试(输入:非UTF-8)
echo "ZWSP (输入:非UTF-8)\n-----\n";
echo "in: $input_zwsp--\nhex: ".bin2hex($input_zwsp)."\n";
$output = preg_replace('/'.$zwsp.'/u', '', $input_zwsp);
echo "out: $output--\nhex: ".bin2hex($output)."\n\n";

// ZWSP测试(输入:UTF-8)
echo "ZWSP (输入:UTF-8)\n-----\n";
echo "in: $input_zwsp_utf8--\nhex: ".bin2hex($input_zwsp_utf8)."\n";
$output = preg_replace('/'.$zwsp.'/u', '', $input_zwsp_utf8);
echo "out: $output--\nhex: ".bin2hex($output)."\n\n";

// ZWSP测试(模式:UTF-8,输入:UTF-8)
echo "ZWSP (模式:UTF-8,输入:UTF-8)\n-----\n";
echo "in: $input_zwsp_utf8--\nhex: ".bin2hex($input_zwsp_utf8)."\n";
$output = preg_replace('/'.$zwsp_utf8.'/u', '', $input_zwsp_utf8);
echo "out: $output--\nhex: ".bin2hex($output)."\n\n";

输出结果

NBSP
-----
in:  --
hex: c2a0
out: --
hex:

ZWSP (输入:非UTF-8)
-----
in:
     --
hex: 200b
out: --
hex:

ZWSP (输入:UTF-8)
-----
in: ​--
hex: e2808b
out: ​--
hex: e2808b // 预期输出应为空

ZWSP (模式:UTF-8,输入:UTF-8)
-----
in: ​--
hex: e2808b
out: ​--
hex: e2808b // 预期输出应为空

解决方案

问题根源在于正则模式的定义:你用单引号包裹十六进制转义序列,PHP不会解析这些转义,而是将其当作普通字符串(比如'\xE2\x80\x8B'实际是字符串\xE2\x80\x8B,而非对应的UTF-8字符)。

有两种正确的解决方式:

方式1:用双引号定义模式变量

让PHP解析十六进制转义,生成对应的ZWSP字符:

$zwsp_utf8 = "\xE2\x80\x8B"; // 双引号包裹,PHP解析为ZWSP字符
$output = preg_replace('/' . $zwsp_utf8 . '/u', '', $input_zwsp_utf8);

方式2:直接使用Unicode码点转义

ZWSP的Unicode码点是U+200B,直接在正则中用\u{200B}匹配,更直观且避免编码转义问题:

$output = preg_replace('/\u{200B}/u', '', $input_zwsp_utf8);

修改后的验证示例:

$input_zwsp_utf8 = "\xE2\x80\x8B";

// 方式1测试
$zwsp_utf8 = "\xE2\x80\x8B";
$output1 = preg_replace('/' . $zwsp_utf8 . '/u', '', $input_zwsp_utf8);

// 方式2测试
$output2 = preg_replace('/\u{200B}/u', '', $input_zwsp_utf8);

// 输出结果均为空
var_dump(bin2hex($output1)); // string(0) ""
var_dump(bin2hex($output2)); // string(0) ""

以上两种方式都能正确匹配并替换UTF-8编码的ZWSP字符。

内容的提问来源于stack exchange,提问作者clarkk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 02:07:24