我已经看了堆栈溢出(替换字符..呃,JavaScript如何不遵循Unicode标准的RegExp等),并没有真正找到一个具体的答案的问题“JavaScript如何匹配重音字符(那些变音符标记)?”

我强迫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.+$/;

这将匹配几乎任何东西,至少以:某物,某物的形式。我想还可以……


我刚刚发现的最后一种方法可能更简单……

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

它匹配了一系列Unicode字符——经过测试并能正常工作,尽管我没有尝试任何疯狂的东西,只是我在我们语言系看到的教员名字的正常内容。


以下是我的担忧:

The first solution is far too limiting, and sloppy and convoluted at that. It would need to be changed if I forgot a character or two, and that's just not very practical. The second solution is better, concise, but it probably matches far more than it actually should. I couldn't find any real documentation on exactly what . matches, just the generalization of "any character except the newline character" (from a table on the MDN). The third solution seems the be the most precise, but are there any gotchas? I'm not very familiar with Unicode, at least in practice, but looking at a code table/continuation of that table, \u00C0-\u017F seems to be pretty solid, at least for my expected input.

老师们提交的表格不会用他们的母语(如阿拉伯语、中文、日语等)写他们的名字,所以我不必担心不符合拉丁字符集的字符


这三种方法中哪一种最适合这项任务?或者有没有更好的解决方案?


当前回答

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

要精确匹配所有拉丁字符及其重音版本,Unicode范围可能提供了最佳解决方案。它们可以扩展到所有非空白字符,这可以使用\S字符类来实现。

我强迫一个字段在一个UI匹配的格式:last_name, first_name(最后[逗号空格]第一)

我在这里看到的最基本的问题不是变音符,而是空格。有一些名称由多个单词组成,例如标题。所以你应该使用最通用的,那就是允许所有的东西,但逗号区分姓和名:

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

但是你的第二个解决方案。字符类也很好,你可能只需要关心多个逗号。

其他回答

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

要精确匹配所有拉丁字符及其重音版本,Unicode范围可能提供了最佳解决方案。它们可以扩展到所有非空白字符,这可以使用\S字符类来实现。

我强迫一个字段在一个UI匹配的格式:last_name, first_name(最后[逗号空格]第一)

我在这里看到的最基本的问题不是变音符,而是空格。有一些名称由多个单词组成,例如标题。所以你应该使用最通用的,那就是允许所有的东西,但逗号区分姓和名:

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

但是你的第二个解决方案。字符类也很好,你可能只需要关心多个逗号。

我的上下文略有不同,仅限于法语:我想通过允许出现口音错误来搜索文本。

例如,我想搜索“maîtrisée”,但要搜索的文本是“…”maitrisee……”。所以,我在JavaScript中使用了正则表达式/ma[I |î|ï]tris[e|é|è|ê|ë]/。

在表达式中,'['和']'定义了一组字符,'|'是一个OR条件。

这个页面给出了一个重音字符的列表:Diacritiques utilisés en français

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

[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字符表。

XRegExp库有一个名为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>

你可以用这个:

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

它将匹配每个单词是否带有重音字符。