PHP全角转半角转换方法指南:正则与映射函数对比

夏知夏
夏知夏
发布时间:2026-10-13 | 3人浏览过
原创

在Web开发中,处理用户输入或数据清洗时常需将全角字符(如0123ABC)统一为半角字符。本文汇总了PHP环境下常用的全角转半角技术方案,包括针对特定编码的正则表达式技巧、UTF-8下的字节序列匹配,以及通用的数组映射替换函数,帮助开发者根据实际场景选择最优解。

了解全角与半角及编码影响

全角字符占用两个字节的空间,常见于中文输入法状态下的数字、字母和符号;半角字符通常占用一个字节。在进行转换时,首要前提是确认服务器运行环境的字符集编码(如 GBK/GB2312 或 UTF-8),因为不同的编码方式决定了底层字节的存储结构,进而影响正则表达式和替换逻辑的有效性。

方法一:基于GBK编码的正则表达式替换

如果项目使用的是 GBK 或 GB2312 等非UTF-8编码,可以利用全角字符与半角字符在ASCII码值上的固定差值进行转换。全角字符的第二个字节减去 0x80(即128)即可得到对应的半角字节值。

适用条件: 环境编码必须为 GBK/GB2312,且无需支持生僻字或特殊标点。 操作逻辑: 使用 preg_replace 的 /e 修饰符(注意:e 修饰符在 PHP 7.0.0 已弃用,PHP 8.0.0 移除,现代开发建议使用 preg_replace_callback)执行代码求值。

<?php
$str = "0123ABCDWShall?&amp;amp;&{}[]*^%#@!~()+-|:";
echo "原字符串 (全角):" . $str . "<br>";
// 注意:此方法依赖 /e 模式,在新版 PHP 中不推荐直接使用
// 建议重构为 preg_replace_callback 以实现安全转换
$str = preg_replace('/\xa3([\xa1-\xfe])/e', 'chr(ord(\1)-0x80)', $str);
echo "转换后字符串: " . $str;
?>

风险提示: 上述代码使用了 deprecated 的 /e 模式。在实际生产环境中,若坚持使用正则数学运算逻辑,应将其封装为回调函数,并务必先备份代码或使用版本控制。

方法二:针对 UTF-8 的多字节正则匹配

当服务器使用 UTF-8 编码时,每个汉字或全角字符由多个字节组成(通常为3个字节)。此时不能简单按单字节处理,而需匹配特定的字节序列范围。

<?php
// 定义全角数字和字母的映射表
$queue = Array(
    '0' => '0', '1' => '1', '2' => '2', '3' => '3', '4' => '4',
    '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9',
    'A' => 'A', 'B' => 'B', 'C' => 'C', 'D' => 'D', 'E' => 'E',
    'F' => 'F', 'G' => 'G', 'H' => 'H', 'I' => 'I', 'J' => 'J',
    'K' => 'K', 'L' => 'L', 'M' => 'M', 'N' => 'N', 'O' => 'O',
    'P' => 'P', 'Q' => 'Q', 'R' => 'R', 'S' => 'S', 'T' => 'T',
    'U' => 'U', 'V' => 'V', 'W' => 'W', 'X' => 'X', 'Y' => 'Y',
    'Z' => 'Z', 'a' => 'a', 'b' => 'b', 'c' => 'c', 'd' => 'd',
    'e' => 'e', 'f' => 'f', 'g' => 'g', 'h' => 'h', 'i' => 'i',
    'j' => 'j', 'k' => 'k', 'l' => 'l', 'm' => 'm', 'n' => 'n',
    'o' => 'o', 'p' => 'p', 'q' => 'q', 'r' => 'r', 's' => 's',
    't' => 't', 'u' => 'u', 'v' => 'v', 'w' => 'w', 'x' => 'x',
    'y' => 'y', 'z' => 'z'
);

// 匹配 UTF-8 下全角数字和字母的字节序列
// EF BC 90-99 对应全角 0-9
// EF BD 81-9A, A1-B9 对应全角 A-Z, a-z
$result = preg_replace_callback("/([\xEF][\xBC][\x90-\x99]|[\xEF][\xBD][\x81-\x9A\xA1-\xBA])/", function($matches) use ($queue) {
    return $queue[$matches[1]] ?? $matches[1];
}, "0123ABCDabcd");

echo $result;
?>

完成判断: 输出结果应为标准的 ASCII 半角字符串。此方法准确度高,但仅覆盖了数字和部分英文字母,标点符号需额外扩展规则。

方法三:通用双向映射法(推荐用于现代 PHP)

最稳健且不依赖底层编码细节的方法是使用数组映射结合 str_replace 或 strtr。这种方法清晰易懂,支持全角到半角(TOSBC)和半角到全角(TODBC)的双向转换。

<?php
function convertStrType($str, $type) {
    // 全角字符列表
    $dbc = array(
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
        'U', 'V', 'W', 'X', 'Y', 'Z',
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
        'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
        'u', 'v', 'w', 'x', 'y', 'z',
        '-', ' ', ':', '.', ',', '/', '%', '#', '!', '@',
        '&', '(', ')', '<', '>', '"', ''', '?', '[', ']',
        '{', '}', '\\', '|', '+', '=', '_', '^', '¥', '~', '`'
    );
    
    // 对应的半角字符列表
    $sbc = array(
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
        'U', 'V', 'W', 'X', 'Y', 'Z',
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
        'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
        'u', 'v', 'w', 'x', 'y', 'z',
        '-', ' ', ':', '.', ',', '/', '%', '#', '!', '@',
        '&', '(', ')', '<', '>', '"', ''', '?', '[', ']',
        '{', '}', '\\', '|', '+', '=', '_', '^', '&#65039', '~', '`'
    );

    if ($type == 'TODBC') {
        // 半角转全角
        return str_replace($sbc, $dbc, $str);
    } elseif ($type == 'TOSBC') {
        // 全角转半角
        return str_replace($dbc, $sbc, $str);
    }
    return $str;
}

// 示例调用
$input = "Hello0123!";
$output = convertStrType($input, 'TOSBC');
echo $output; // 输出: Hello0123!
?>

优势分析: str_replace 会并行执行替换,对于短字符串性能极佳。由于不涉及正则表达式的回溯开销,代码可读性最强,且易于维护新增的字符映射关系。

方法四:简化标点与符号映射

若只需转换部分常见标点(如括号、百分号、加减号等),可使用更精简的映射数组配合 strtr。strtr 比 str_replace 更快,因为它一次性构建映射表。

<?php
function make_semiangle($str) {
    $arr = array(
        '0' => '0', '1' => '1', '2' => '2', '3' => '3', '4' => '4',
        '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9',
        'A' => 'A', 'B' => 'B', 'C' => 'C', 'D' => 'D', 'E' => 'E',
        'F' => 'F', 'G' => 'G', 'H' => 'H', 'I' => 'I', 'J' => 'J',
        'K' => 'K', 'L' => 'L', 'M' => 'M', 'N' => 'N', 'O' => 'O',
        'P' => 'P', 'Q' => 'Q', 'R' => 'R', 'S' => 'S', 'T' => 'T',
        'U' => 'U', 'V' => 'V', 'W' => 'W', 'X' => 'X', 'Y' => 'Y',
        'Z' => 'Z', 'a' => 'a', 'b' => 'b', 'c' => 'c', 'd' => 'd',
        'e' => 'e', 'f' => 'f', 'g' => 'g', 'h' => 'h', 'i' => 'i',
        'j' => 'j', 'k' => 'k', 'l' => 'l', 'm' => 'm', 'n' => 'n',
        'o' => 'o', 'p' => 'p', 'q' => 'q', 'r' => 'r', 's' => 's',
        't' => 't', 'u' => 'u', 'v' => 'v', 'w' => 'w', 'x' => 'x',
        'y' => 'y', 'z' => 'z',
        '(' => '(', ')' => ')', '【' => '[', '】' => ']', '{' => '{', '}' => '}',
        '《' => '<', '》' => '>',
        '%' => '%', '+' => '+', '—' => '-', '-' => '-', '~' => '~',
        ':' => ':', '。' => '.', '、' => ',', ',' => ',', ';' => ';',
        '?' => '?', '!' => '!', '…' => '-', '|' => '|',
        '“' => '"', '”' => '"', '‘' => ''', ''' => ''''', '|' => '|'
    );
    return strtr($str, $arr);
}
?>

以上即为PHP实现全角字符转为半角方法的详细内容,更多关于PHP字符处理技巧的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表