JavaScript 字串操作:大小寫轉換
簡介
在前端開發與 Node.js 後端程式中,字串的大小寫轉換是最常見的文字處理需求之一。無論是搜尋關鍵字、比對使用者輸入、產生友善的 URL,或是將資料庫中的資料正規化,正確且有效的大小寫操作都能提升程式的可靠度與使用者體驗。
JavaScript 內建的 String 方法提供了簡潔的 API,讓我們可以在 單行程式碼 內完成大小寫的變換;同時,面對多語系(如中文、日文、土耳其文)時,了解 locale 相關的 API 也是不可或缺的技能。
本篇文章將從基礎概念說明開始,逐步帶領讀者掌握 toUpperCase、toLowerCase、toLocaleUpperCase、toLocaleLowerCase 等方法的使用方式,並提供實務上常見的範例、陷阱與最佳實踐,幫助你在日常開發中更得心應手。
核心概念
1. 基本的大小寫方法
| 方法 | 說明 | 範例 |
|---|---|---|
String.prototype.toUpperCase() |
將字串全部轉成 大寫(英文字母) | hello.toUpperCase() → "HELLO" |
String.prototype.toLowerCase() |
將字串全部轉成 小寫(英文字母) | WORLD.toLowerCase() → "world" |
程式碼範例 1:最簡單的轉換
// 原始字串
const raw = "JavaScript is Awesome!";
// 轉成大寫
const upper = raw.toUpperCase(); // "JAVASCRIPT IS AWESOME!"
// 轉成小寫
const lower = raw.toLowerCase(); // "javascript is awesome!"
console.log(upper);
console.log(lower);
註解:
toUpperCase()與toLowerCase()只會影響 英文字母,對於其他 Unicode 字元(如德文 ß、土耳其 i)不會進行語系特化的轉換。
2. 語系感知的大小寫轉換
在多語系環境下,某些字母的大小寫規則與英文字母不同。例如:
- 土耳其文的
i(小寫)對應的大寫是İ(帶點的大寫 I)。 - 德文的
ß(小寫)在大寫時會變成SS。
此時,我們需要使用 toLocaleUpperCase() / toLocaleLowerCase() 並傳入目標語系代碼(如 'tr'、'de')。
程式碼範例 2:Locale‑aware 轉換
const turkish = "istanbul";
// 以土耳其語系轉成大寫
const upperTr = turkish.toLocaleUpperCase('tr'); // "İSTANBUL"
console.log(upperTr);
// 以德語語系轉成大寫(ß → SS)
const german = "straße";
const upperDe = german.toLocaleUpperCase('de'); // "STRASSE"
console.log(upperDe);
註解:如果不提供語系參數,瀏覽器會使用執行環境的預設語系,結果可能與期望不符。
3. 首字母大寫(Title Case)
許多 UI 需求會將每個單字的 首字母 轉成大寫,剩餘字母保持小寫,例如「hello world」 → 「Hello World」。這個需求無法直接透過內建方法完成,需要 結合正規表達式 與 replace。
程式碼範例 3:實作 toTitleCase 函式
/**
* 將字串轉成 Title Case(每個單字首字母大寫)
* @param {string} str 輸入字串
* @returns {string} 轉換後的字串
*/
function toTitleCase(str) {
return str
.toLowerCase() // 先全部小寫,避免混雜大小寫
.replace(/\b\w/g, char => char.toUpperCase()); // \b 為單字邊界
}
// 範例
const sentence = "jAvAsCrIpT is fuN!";
console.log(toTitleCase(sentence)); // "Javascript Is Fun!"
註解:
/\b\w/g會匹配每個單字的第一個字母;使用char => char.toUpperCase()只對匹配到的字元做大寫處理。
4. Unicode 正規化與大小寫折疊(Case Folding)
在比較字串時,單純的 toUpperCase() / toLowerCase() 可能無法處理 合成字(如 é)與 分解字(如 e + ´)的等價性。使用 String.prototype.normalize() 配合 大小寫折疊(Case Folding)可確保比較的正確性。
程式碼範例 4:Unicode 正規化後再比較
const a = "e\u0301"; // e + ́ (分解形式)
const b = "\u00e9"; // é (合成形式)
// 直接比較會得到 false
console.log(a === b); // false
// 正規化為 NFC(合成形式)後再比較
const aNorm = a.normalize('NFC');
const bNorm = b.normalize('NFC');
console.log(aNorm === bNorm); // true
// 若要忽略大小寫差異,可再做一次 toLowerCase()
console.log(aNorm.toLowerCase() === bNorm.toLowerCase()); // true
註解:
normalize('NFC')會把分解形式合併成單一字元,適合在 搜尋、去重 時使用。
5. 變更字串中的特定部分大小寫
有時候我們只想改變字串中 某段文字 的大小寫,例如把 URL 中的查詢參數名稱全部改成小寫,以符合 API 規範。
程式碼範例 5:使用 replace 搭配回呼函式
const url = "https://example.com/SEARCH?QUERY=JavaScript&Page=2";
// 把所有查詢參數名稱改成小寫
const normalized = url.replace(/([?&])([^=]+)=/g, (match, p1, p2) => {
return `${p1}${p2.toLowerCase()}=`;
});
console.log(normalized);
// https://example.com/SEARCH?query=JavaScript&page=2
註解:正規表達式
([?&])([^=]+)=捕獲「?」或「&」之後的參數名,回呼函式內只對參數名 (p2) 做toLowerCase()。
常見陷阱與最佳實踐
| 陷阱 | 說明 | 解決方案 |
|---|---|---|
| 忘記考慮語系 | 直接使用 toUpperCase() 會在土耳其文、德文等語系產生錯誤結果。 |
依需求使用 toLocaleUpperCase('tr')、toLocaleLowerCase('de')。 |
| 字串不可變 | toUpperCase() 不會改變原字串,若直接使用 str.toUpperCase(); 而不存回變數,結果會遺失。 |
務必把回傳值賦給變數 或直接在表達式中使用。 |
| Unicode 合成字 | 比較含有合成/分解字元的字串時,=== 可能得到 false。 |
使用 normalize() 統一字元形式,必要時再做大小寫折疊。 |
| 正規表達式的全域旗標 | 在 replace 中忘記加 g,只會替換第一個匹配項目。 |
確認正則式加上 g(全域)或在迴圈中多次呼叫。 |
| 多字元變換 | 某些語系的大寫會產生 多個字元(如 ß → SS),直接取字串長度可能不符合預期。 |
轉換後以 字元陣列 (Array.from()) 處理,避免因 Unicode surrogate pair 產生錯誤。 |
最佳實踐:
- 先正規化再比較:
str1.normalize('NFC') === str2.normalize('NFC')。 - 針對使用者輸入使用 locale:表單驗證或搜尋時,使用
toLocaleLowerCase()以確保語系正確。 - 保持函式純粹:大小寫轉換函式不應產生副作用,僅回傳新字串。
- 利用工具函式:將常用的
toTitleCase、normalizeAndFold包裝成模組,提升程式碼可讀性與重用性。
實際應用場景
搜尋功能的大小寫不敏感
在前端即時搜尋時,將使用者輸入與資料庫回傳的文字都 normalize + toLowerCase,即可實現不分大小寫、且支援 Unicode 的搜尋。RESTful API 的參數正規化
為避免大小寫混用導致 404 錯誤,後端在解析路由時會把路徑與查詢參數全部 toLocaleLowerCase('en'),確保一致性。自動產生檔案或變數名稱
例如將使用者提供的標題My New Blog Post轉成檔名my-new-blog-post.md,常見做法是toLowerCase()加上正則式替換空白與特殊字元。多語系 UI 的文字顯示
在國際化(i18n)專案中,根據使用者語系自動把 UI 文本的首字母大寫,提升閱讀體驗。資料清理與去重
在將大量資料匯入資料庫前,先將關鍵欄位normalize + toUpperCase,確保相同文字不因大小寫或 Unicode 形式差異被視為不同紀錄。
總結
toUpperCase/toLowerCase:最簡單的英文字母大小寫轉換。toLocaleUpperCase/toLocaleLowerCase:在多語系環境下必須使用,避免語系特有的錯誤。- 正規化 (
normalize) + 大小寫折疊:確保 Unicode 合成/分解字元比較的一致性。 - 自訂函式(如
toTitleCase):結合正規表達式可快速完成常見的首字母大寫需求。 - 最佳實踐:始終把轉換結果存回變數、考慮語系、在比較前正規化,並將常用邏輯抽離成可重用的工具函式。
掌握上述概念與技巧,你就能在 JavaScript 中自如地處理各種大小寫相關的文字需求,寫出既 正確 又 易維護 的程式碼。祝你開發順利,寫出更乾淨、更可靠的程式!