用于重音字符的具体Javascript正则表达式(变音符号)

时间:2013-12-19 19:54:44

标签: javascript regex unicode

我查看了Stack Overflow(replacing characters.. ehhow JavaScript doesn't follow the Unicode standard concerning RegExp等),并没有真正找到问题的具体答案:

How can JavaScript match for accented characters (those with diacritical marks)?

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

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

/^[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的形式。我觉得那没问题......

最后一种方法,我只是found可能更简单......

/^[a-zA-Z\u00C0-\u017F]+,\s[a-zA-Z\u00C0-\u017F]+$/
  • 它匹配了一系列unicode字符 - 经过测试和工作,虽然我没有尝试任何疯狂的事情,只是我在语言部门看到的教职员工的正常情况。

以下是我的担忧:

  1. 第一种解决方案太局限了,而且很邋and和错综复杂。如果我忘了一两个字,那就需要改变,这不太实际。
  2. 第二种解决方案更好,更简洁,但它可能比实际应用的更多。我找不到关于完全 .匹配的任何真实文档,只是“除了换行符之外的任何字符”的概括(来自MDN上的表)。
  3. 第三种解决方案似乎是最精确的,但有任何问题吗?我不是很熟悉Unicode,至少在实践中,但是看code table / continuation of that table\u00C0-\u017F似乎非常可靠,至少对我预期的输入而言。

    • 教师不会以母语提交表格(例如阿拉伯语,中文,日语等),所以我不必担心拉丁字符集的字符

  4. 所以真正的问题:这三种方法中哪一种最适合这项任务?或者有更好的解决方案吗?

9 个答案:

答案 0 :(得分:172)

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

[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 [ ] ^ \ × ÷

有关以数字顺序列出的字符,请参阅https://unicode-table.com/en/

答案 1 :(得分:22)

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

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

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

如果您需要更多代码点,可以在Wikipedia List of Unicode characters上找到更多范围。例如,您还可以添加Latin Extended-CDE,但我将它们排除在外,因为现在只有历史学家对它们感兴趣,而且D和E集合甚至都没有在我的浏览器中正确呈现。

原始的正则表达式在\u017F停止,名为“Şenol”。根据{{​​3}},第一个字符是\u0218,拉丁语大写字母以下是COMMA。 (是的,它通常拼写为cedilla-S \u015E,“Şenol。”但我不是飞往土耳其去告诉他,“你拼错了你的名字!”

答案 2 :(得分:14)

  

这三种方法中哪一种最适合这项任务?

取决于任务:-)为了完全匹配所有拉丁字符及其重音版本,Unicode范围可能提供最佳解决方案。它们可能会扩展到所有非空白字符,这可以使用\S字符类来完成。

  

我正在强制UI中的字段匹配格式:last_name, first_name(最后[逗号空格])

我在这里看到的最基本的问题不是变音符号,而是空格。有几个名称由多个单词组成,例如标题。所以你应该选择最通用的,即允许除了逗号之外的所有内容,首先区别于姓氏:

/[^,]+,\s[^,]+/

但是你使用.字符类的第二个解决方案同样合适,那么你可能只需要关心多个commata。

答案 3 :(得分:13)

XRegExp库有a plugin named Unicode,有助于解决此类任务。

<script src="xregexp.js"></script>
<script src="addons/unicode/unicode-base.js"></script>
<script>
  var unicodeWord = XRegExp("^\\p{L}+$");

  unicodeWord.test("Русский"); // true
  unicodeWord.test("日本語"); // true
  unicodeWord.test("العربية"); // true
</script>

在问题的评论中提到过,但很容易错过。我提交这个答案之后才注意到它。

答案 4 :(得分:8)

这个怎么样?

/^[a-zA-ZÀ-ÖØ-öø-ÿ]+$/

答案 5 :(得分:5)

来自这个维基:https://en.wikipedia.org/wiki/List_of_Unicode_characters#Basic_Latin

对于拉丁字母,我使用

/^[A-zÀ-ÖØ-öø-ÿ]+$/ 

它避免使用连字符和特殊字符

答案 6 :(得分:5)

/^[\pL\pM\p{Zs}.-]+$/u

说明:

  • \pL-匹配来自任何语言的任何字母
  • \pM-附加一个打算与其他字符组合的字符(例如重音符号,变音符,包围盒等)
  • \p{Zs}-匹配不可见但占用空间的空白字符
  • u-模式和主题字符串被视为UTF-8

与其他拟议的正则表达式(例如[A-Za-zÀ-ÖØ-öø-ÿ])不同,这将适用于所有特定于语言的字符,例如Šš符合此规则,但与此页面上的其他人不匹配。

不幸的是,JavaScript本身不支持这些类。但是,您可以使用xregexp,例如

const XRegExp = require('xregexp');

const isInputRealHumanName = (input: string): boolean => {
  return XRegExp('^[\\pL\\pM-]+ [\\pL\\pM-]+$', 'u').test(input);
};

答案 7 :(得分:4)

那呢?

^([a-zA-Z]|[à-ú]|[À-Ú])+$

它将匹配每个带有重音符号的单词。

答案 8 :(得分:2)

您可以使用以下方法从字母中删除变音符号:

var str = "résumé"
str.normalize('NFD').replace(/[\u0300-\u036f]/g, '') // returns resume

它将删除所有变音符, 然后在上面执行正则表达式

参考:

https://thread.engineering/2018-08-29-searching-and-sorting-text-with-diacritical-marks-in-javascript/