【问题标题】:Why regular expression for cyrillic letters misses a letter? [duplicate]为什么西里尔字母的正则表达式会漏掉一个字母? [复制]
【发布时间】:2014-11-04 09:05:53
【问题描述】:

我想验证 html 页面中的文本输入字段以仅接受西里尔字母。我使用正则表达式在 JavaScript 中编写了验证代码,如下所示:

var namevalue = document.getElementById("name")
var letters = /^[А-Яа-я]+$/;
if (namevalue.matches(letters)) {
  alert("Accepted");
}
else {
  alert("Enter only cyrillic letters");
}

此代码适用于所有西里尔字母,除了Ё ё

【问题讨论】:

  • 试试这个:var letters = /^[А-Яа-яёЁ]+$/;
  • @MarkZucchini:这不是字符类的工作方式。删除|
  • “仅西里尔字母”要求含糊不清,因为有很多语言使用西里尔字母的子集,并且在一种语言中有效的字符在另一种语言中不存在。您要匹配哪种语言
  • 是的。 ё 不工作的问题是因为它超出了 A-Я 范围。 A-Я 是一个基本的西里尔字母 [0430-044F],但 ё 不在那个基本字母表中。它是西里尔文扩展名 [0400-045F]。因此,javascript 正则表达式不是通过字母本身进行比较,而是通过其字符码进行比较,所以 ё 超出了范围。

标签: javascript html regex


【解决方案1】:

ё 无法正常工作的问题,因为它超出了Aа-Яя 的范围。 Aа-Яа 属于基本西里尔字母 [0430-044F],但ё 不在那个基本西里尔字母 中。 ё 属于 西里尔文扩展 [0400-045F]。因为,JavaScript 正则表达式引擎不是通过字母本身而是通过其字符代码进行比较,所以 ё 只是超出了范围。

因为我认为您的意思是现代俄语,尽管ё 很少见但仍在广泛使用 我可能会建议这个解决方案

var namevalue = document.getElementById("name")

// please note that I added to your pattern "еЁ".
// now this matches all Russian cyrillic letters both small and caps
// plus ё and Ё
var letters = /^[А-Яа-яёЁ]+$/; 

if (namevalue.matches(letters)) {
   alert("Accepted");
}
else {
   alert("Enter only cyrillic letters");
} 

不幸的是,A-ЯЁ 的问题深埋在 Unicode 规范中。没有简单明了的解决方案。因此,对于健壮的编程,您需要始终为这种情况做好准备。

【讨论】:

  • 既然JS保证大小写正确折叠,可以简单的/^[а-яё]+$/i
【解决方案2】:

您可以在西里尔字母扩展中找到ёЁ,而不是在А-Яа-я t中找到

【讨论】:

    【解决方案3】:

    Ë 不一定在西里尔字母中,因此,不在您使用的 А-Яа-я 范围内。

    您的 Ë 西里尔文:U+0401 还是拉丁文:U+00CB

    如果您还想捕捉非西里尔字母 Ë's ,您可能需要将此范围添加到您的正则表达式中:À-ÿ:

    alert(JSON.stringify("Ëë".match(/^[À-ÿ]+$/)))

    如果您只想在西里尔字母中捕捉Ë,试试这个:

    不要从U+0410 (А) 开始您的范围,而是从U+0400 (Ѐ) 开始并以U+045F (џ) 结束:

    alert(JSON.stringify("Ёё".match(/^[Ѐ-џ]+$/)))

    (最后一个范围应包括完整的西里尔字母。)

    来源:Unicode character codes.您可以使用此页面来检查需要添加到正则表达式的范围。

    【讨论】:

    • 我不知道如何评价第一个选项。它在视觉上类似于西里尔字母变音符号 (U+0451),但它是拉丁字母(不太可能混入西里尔字母)。我认为您的第二个解决方案可能是 OP 想要的,但它将包含一堆未使用的西里尔字符。
    • 是的,这有点问题。我不熟悉西里尔文,所以我不知道什么是字符,也没有使用过。如果你是,请建议一个更好的使用范围:-)
    • 除非您只想迎合一种语言,否则您将始终使用未使用的西里尔字符。它们都在一些语言中使用(他们不会存在!),但没有单一语言使用它们
    • 还有另一件事 - 这可能是有问题的:并非所有重音西里尔字符都被编码,这意味着您可能必须考虑组合标记。
    • 拉丁字母Ë在这种情况下是不相关的。如果要允许形状与西里尔字母相同的拉丁字母,则需要允许更多;专门允许拉丁语 Ë 会很奇怪。答案的另一部分的问题是允许任意收集西里尔字母,拒绝其中的许多字母。表达式并不代表所有西里尔字母,但也不代表俄语中使用的一组字母,这显然是本意。
    猜你喜欢
    • 1970-01-01
    • 2013-03-29
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多