重音字符(音调符号)的具体 JavaScript 正则表达式

2022-08-30 00:29:16

我已经看过Stack Overflow(替换字符..ehJavaScript如何不遵循关于RegExp的Unicode标准等),并且没有真正找到具体的答案来回答“JavaScript如何匹配重音字符(带有变音符号的字符)?"

我强制UI中的字段匹配格式:(最后一个[逗号空格]第一),我想提供对变音符号的支持,但显然在JavaScript中,它比其他语言/平台更困难。last_name, first_name

这是我的原始版本,直到我想添加变音符号支持:

/^[a-zA-Z]+,\s[a-zA-Z]+$/

目前,我正在讨论添加支持的三种方法之一,所有这些方法我都经过测试和工作(至少在某种程度上,我真的不知道第二种方法的“程度”是什么)。它们分别是:

明确列出所有我想接受为有效的重音字符(蹩脚且过于复杂):


var accentedCharacters = "àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ";
// Build the full regex
var regex = "^[a-zA-Z" + accentedCharacters + "]+,\\s[a-zA-Z" + accentedCharacters + "]+$";
// Create a RegExp from the string version
regexCompiled = new RegExp(regex);
// regexCompiled = /^[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+,\s[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+$/
  • 这会将姓氏/名字与 中任何受支持的重音字符正确匹配。accentedCharacters

我的另一种方法是使用字符类,以获得更简单的表达式:.

var regex = /^.+,\s.+$/;
  • 这几乎可以匹配任何东西,至少以以下形式:。我想没关系...something, something

最后一种方法,我刚刚发现可能更简单...

/^[a-zA-Z\u00C0-\u017F]+,\s[a-zA-Z\u00C0-\u017F]+$/
  • 它匹配了一系列Unicode字符 - 经过测试和工作,尽管我没有尝试任何疯狂的东西,只是我在语言部门看到的教职员工姓名的正常内容。

以下是我的担忧:

  1. 第一种解决方案限制性太强,而且草率而复杂。如果我忘记了一两个角色,就需要改变它,这并不是很实用。

  2. 第二种解决方案更好,更简洁,但它可能比实际应该匹配的要多得多。我找不到任何关于确切匹配内容的真实文档,只是“除换行符以外的任何字符”的概括(来自MDN上的表格)。.

  3. 第三种解决方案似乎是最精确的,但是有什么陷阱吗?我对Unicode不是很熟悉,至少在实践中是这样,但是看看代码表/该表的延续,似乎非常可靠,至少对于我预期的输入而言。\u00C0-\u017F

  • 教师不会提交带有其母语(例如,阿拉伯语,中文,日语等)名称的表格,因此我不必担心拉丁字符集以外的字符

这三种方法中哪一种最适合该任务?还是有更好的解决方案?


答案 1

接受所有口音的更简单方法是:

[A-zÀ-ú] // accepts lowercase and uppercase characters
[A-zÀ-ÿ] // as above, but including letters with an umlaut (includes [ ] ^ \ × ÷)
[A-Za-zÀ-ÿ] // as above but not including [ ] ^ \
[A-Za-zÀ-ÖØ-öø-ÿ] // as above, but not including [ ] ^ \ × ÷

有关按数字顺序列出的字符,请参阅 Unicode 字符表


答案 2

重音拉丁语范围对于我的名字数据库来说还不够,所以我将正则表达式扩展到\u00C0-\u017F

[a-zA-Z\u00C0-\u024F]
[a-zA-Z\u00C0-\u024F\u1E00-\u1EFF] // includes even more Latin chars

我添加了这些代码块(一次包含三个相邻的块):\u00C0-\u024F

请注意,这实际上只是拉丁语-1补充的一部分。它跳过了不可打印的控制信号和除以÷×的笨拙放置的乘法之外的所有符号。\u00C0-\u00FF\u00D7\u00F7

[a-zA-Z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u024F] // exclude ×÷

如果你需要更多的码位,你可以在维基百科的Unicode字符列表中找到更多的范围。例如,你也可以添加拉丁语扩展-CDE,但我省略了它们,因为现在只有历史学家似乎对它们感兴趣,D和E集甚至在我的浏览器中都没有正确呈现。

最初的正则表达式停在“Șenol”这个名字上。根据FontSpace的Unicode Analyzer,第一个字符是拉丁大写字母S,下面有逗号。(是的,它通常拼写为cedilla-S,“Şenol”。但我不会飞到土耳其去告诉他,“你拼错了你的名字!”)\u017F\u0218\u015E