HOWTO · JavaScript

JavaScript 中不区分大小写的字符串比较

介绍如何在 JavaScript 中进行不区分大小写的字符串相等比较,并说明何时使用 localeCompare() 或正则表达式,以及这些方法的适用范围。

本页内容

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();需要匹配模式时再用正则表达式。