我查看了Stack Overflow(replacing characters.. eh,how 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
的形式。我觉得那没问题...... /^[a-zA-Z\u00C0-\u017F]+,\s[a-zA-Z\u00C0-\u017F]+$/
以下是我的担忧:
.
匹配的任何真实文档,只是“除了换行符之外的任何字符”的概括(来自MDN上的表)。 第三种解决方案似乎是最精确的,但有任何问题吗?我不是很熟悉Unicode,至少在实践中,但是看code table / continuation of that table,\u00C0-\u017F
似乎非常可靠,至少对我预期的输入而言。
所以真正的问题:这三种方法中哪一种最适合这项任务?或者有更好的解决方案吗?
答案 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
一次包含三个相邻的块):
\u00C0-\u00FF
Latin-1 Supplement \u0100-\u017F
Latin Extended-A \u0180-\u024F
Latin Extended-B \u1E00-\u1EFF
Latin Extended Additional 如果您需要更多代码点,可以在Wikipedia List of Unicode characters上找到更多范围。例如,您还可以添加Latin Extended-C,D和E,但我将它们排除在外,因为现在只有历史学家对它们感兴趣,而且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
它将删除所有变音符, 然后在上面执行正则表达式
参考: