HOWTO · JavaScript

JavaScript 中不區分大小寫的字串比較

說明如何在 JavaScript 中進行不區分大小寫的字串比較,並介紹字串相等、語言排序與正規表示式比對各自適用的情境。

本頁內容

JavaScript 的字串相等比較會區分大小寫,因此 "Hello" === "hello" 的結果是 false。若要簡單地檢查兩個字串是否相等而不計大小寫,可以先用 toLowerCase() 將兩者轉成相同大小寫,再比較結果。若等價判定需要遵循特定語言的排序規則,請使用 localeCompare();若要比對的是模式,而不是兩個完整字串,則適合使用正規表示式。

將兩個字串轉成相同大小寫以進行簡單比較

使用嚴格相等運算子比較前,先以相同方式轉換兩個值。常見做法是使用 toLowerCase();也可以依照相同模式使用 toUpperCase(),但兩者沒有哪一種在所有情況下都較適合。大小寫轉換適合一般識別字與使用者輸入,不過它並不是適用於所有 Unicode 情況的大小寫摺疊操作。如果應用程式必須將特定字元視為相同,或必須遵循特定語言規則,請明確選擇並測試所需的行為。

以下範例會先將兩個值轉成小寫,再進行比較:

const first = "Hello";
const second = "hello";
const equalIgnoringCase = first.toLowerCase() === second.toLowerCase();
console.log(equalIgnoringCase);
true

這適用於簡單的相等檢查,因為比較前已將兩個值正規化。大小寫轉換會產生轉換後的字串,不會修改原始值。若要依語言規則判定等價或排序,請使用 localeCompare(),並審慎選擇選項。

需要依語言規則比較時使用 localeCompare()

localeCompare() 會依照字串排序規則進行比較,並回傳一個數字:在所選選項下,若兩個字串等價就回傳零;負數或正數則表示排序先後。若要檢查是否相等,請確認結果是否為零。

sensitivity 選項會控制哪些差異需要納入比較。設為 "accent" 時,大小寫差異會被忽略,但重音符號仍會區分;設為 "base" 時,大小寫與重音符號都可能被忽略。下方範例以 "accent" 比較 "café" 與 "CAFÉ",因此兩者會被視為等價。若使用 "base",不含重音符號的拼法也可能被視為等價。實際排序結果取決於地區設定;若應用程式需要遵循特定語言的排序方式,請傳入地區設定,並確認對使用者重要的字串都符合預期。

const result = "café".localeCompare("CAFÉ", undefined, { sensitivity: "accent" });
console.log(result === 0);
true

若等價判定應遵循語言排序規則,請採用這種方式。若只是一般的不區分大小寫相等檢查,且不需要依特定語言排序,將兩個字串正規化會更簡單。

需要模式比對時使用正規表示式

正規表示式適合尋找符合特定模式的文字。i 旗標會讓比對忽略大小寫,而 test() 則會回報模式是否在字串中的某處符合。這和一般的字串相等比較不同:未錨定的正規表示式可能只符合輸入的一部分。若要與使用者提供的文字進行完全相等的比對,請先跳脫正規表示式中具有特殊意義的字元,再將模式錨定在字串兩端。在 JavaScript 中,$ 也可能在最後一個行終止字元之前符合,因此範例另外加上結尾斷言,以要求比對位置確實在值的末端。建立 RegExp 前,範例會先跳脫提供的文字。

const userText = "JavaScript";
const escapedText = userText.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const exactPattern = new RegExp("^" + escapedText + "$(?![\\s\\S])", "i");
console.log(exactPattern.test("javascript"));
true

若目標是比較兩個字串,使用大小寫轉換或 localeCompare() 通常更清楚。若要重複使用正規表示式呼叫 test(),除非你會刻意管理 lastIndex,否則請避免加上 g 旗標;全域比對會在不同呼叫間改變狀態。簡單來說,一般相等檢查可用大小寫轉換;等價判定受語言排序影響時使用 localeCompare();輸入必須符合某種模式時則使用正規表示式。