在處理使用者輸入、爬蟲資料、匯入 Excel/CSV 檔案時,常遇到「全形數字」(全角數字)如 12345 混雜在資料中。資料庫儲存、數值運算、比對查詢都需要半形(半角)數字。本文提供一個高效的 GetAlabNum() 函數,將全形數字與常見符號批次轉換為半形對應字元。
<?php
/**
* 將字串中的全形數字與符號轉換為半形
* @param string $fnum 輸入字串
* @return string 僅含半形數字與符號的字串,空則回傳 "0"
*/
function GetAlabNum($fnum) {
// 全形字元陣列(數字 0-9 + 常見符號)
$nums = array('0','1','2','3','4','5','6','7','8','9','.','-','+',':');
// 對應半形字元
$fnums = array('0','1','2','3','4','5','6','7','8','9','.','-','+',':');
$fnlen = count($fnums);
// 批次替換全形為半形
for ($i = 0; $i < $fnlen; $i++) {
$fnum = str_replace($nums[$i], $fnums[$i], $fnum);
}
// 進一步過濾:僅保留 ASCII 字元(移除剩餘中文等非目標字元)
$slen = strlen($fnum);
$oknum = '';
for ($i = 0; $i < $slen; $i++) {
// ord > 0x80 視為雙位元組字元(中文等),直接跳過
if (ord($fnum[$i]) > 0x80) $i++;
else $oknum .= $fnum[$i];
}
// 空字串保護
if ($oknum == "") $oknum = "0";
return $oknum;
}
?>
| 全形 (Unicode) | 半形 (ASCII) | 碼位差值 |
|---|---|---|
| 0-9 (U+FF10-FF19) | 0-9 (U+0030-0039) | +0xFEE0 |
| . (U+FF0E) | . (U+002E) | +0xFEE0 |
| - (U+FF0D) | - (U+002D) | +0xFEE0 |
| + (U+FF0B) | + (U+002B) | +0xFEE0 |
| : (U+FF1A) | : (U+003A) | +0xFEE0 |
<?php
$inputs = [
"價格:12345元",
"溫度-25.6℃",
"編號:ABC123", // 含全形英文
"無效輸入:abc中文"
];
foreach ($inputs as $input) {
echo "原始:$input\n";
echo "轉換:" . GetAlabNum($input) . "\n";
echo "---\n";
}
/* 輸出:
原始:價格:12345元
轉換::12345
---
原始:溫度-25.6℃
轉換:-25.6
---
原始:編號:ABC123
轉換::123
---
原始:無效輸入:abc中文
轉換::abc
--- */
?>
現代 PHP 可利用 Normalizer 類別更優雅地處理:
<?php
// 需安裝 intl 擴展
function toHalfWidth($str) {
// NFKC 正規化會自動將全形轉半形(含字母、符號)
$normalized = Normalizer::normalize($str, Normalizer::NFKC);
// 僅保留 ASCII 可列印字元
return preg_replace('/[^\x20-\x7E]/', '', $normalized);
}
echo toHalfWidth("ABC123+-:."); // 輸出:ABC123+-:.
?>
GetAlabNum() 透過陣列映射替換 + ASCII 過濾,高效完成全半形轉換與非目標字元移除。現代專案若已安裝 intl 擴展,推薦使用 Normalizer::NFKC 一站式解決全形字母、數字、符號轉換。根據專案環境選擇適合方案,能顯著提升資料品質與系統健壯度。