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

如何移除iconv转译ASCII字符串中的多余问号字符?

如何移除iconv TRANSLIT转译后的多余问号?

问题场景

我用iconv把UTF-8字符串转译为ASCII可打印字符,代码如下:

$str = 'Thê qúïck 😈 brõwn fõx júmps?😈 Óvér thé lázy dõg?😈';

$out = iconv('UTF-8', 'ASCII//TRANSLIT', $str);

var_dump($out);
// 输出结果:'The quick ? brown fox jumps?? Over the lazy dog??'

现在需要移除转译结果里的多余问号,但要保留//TRANSLIT正常转译的字符(比如áéïõú转成aeiou),不想用逐字符对比的笨方法,求更优解决思路。


解决方案

1. 先过滤不可转译字符,再执行TRANSLIT转译

提前把那些iconv会转成问号的Unicode字符过滤掉,转译后就不会产生多余问号。用正则匹配保留拉丁字符、标点和空白,删掉其他字符:

$str = 'Thê qúïck 😈 brõwn fõx júmps?😈 Óvér thé lázy dõg?😈';

// 过滤非拉丁、非标点、非空白的字符
$filtered = preg_replace('/[^\p{Latin}\p{Punct}\s]/u', '', $str);

$out = iconv('UTF-8', 'ASCII//TRANSLIT', $filtered);
var_dump($out);
// 输出:'The quick  brown fox jumps? Over the lazy dog?'

2. 精准替换转译产生的问号

如果不想提前过滤,可以在转译后,只删除那些对应原字符不是问号的转译问号。用mb_str_split正确拆分多字节原字符串,再逐对应处理:

$str = 'Thê qúïck 😈 brõwn fõx júmps?😈 Óvér thé lázy dõg?😈';
$out = iconv('UTF-8', 'ASCII//TRANSLIT', $str);

$originalChars = mb_str_split($str);
$translitChars = str_split($out);

$final = '';
foreach ($translitChars as $index => $char) {
    if ($char === '?' && isset($originalChars[$index]) && $originalChars[$index] !== '?') {
        continue;
    }
    $final .= $char;
}

var_dump($final);
// 输出:'The quick  brown fox jumps? Over the lazy dog?'

3. 用intl扩展的Transliterator精准控制转译

如果服务器支持intl扩展,用Transliterator可以一步到位生成无多余问号的结果,转译逻辑更灵活:

$str = 'Thê qúïck 😈 brõwn fõx júmps?😈 Óvér thé lázy dõg?😈';

// 转译规则:去变音符号→转拉丁字符→转ASCII→移除非打印字符
$transliterator = Transliterator::create('NFD; [:Nonspacing Mark:] Remove; NFC; Any-Latin; Latin-ASCII; [^\p{Print}] Remove');
$out = $transliterator->transliterate($str);

var_dump($out);
// 输出:'The quick  brown fox jumps? Over the lazy dog?'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 20:51:25