我想创建一个正则表达式,它允许您输入诸如Name
和Surname
之类的值。但是我有一些限制:
'
,-
或
(空格),然后再应用与第一点相同的规则我几乎实现了这一目标,但是仍然无法正常工作。这是我的创作:
/^[A-ZÀ-ž]{1}[a-zà-ž]+[\s\'-]{0,1}(?:(?=[\s\'-]{0,1})[A-ZÀ-ž]{1}[a-zà-ž]+|(?=[\s\'-]{0,1})[a-zà-ž]+)$/i
我想在Javascript中将其与功能.test(value)
一起使用。不幸的是,它也接受这些:
Test
Test -
Test-
test
Test
Test-test
TTest
Test'test
我想被接受和允许的是那些:
Test
Test-Test
Test Test
Test'Test
我不知道我在做什么错以及如何解决这个问题……我在这里缺少什么?
答案 0 :(得分:2)
您的正则表达式在某些地方“太冗长”,例如:
{1}
。默认重复计数仅为1。{0,1}
的缩写可以简化为?
。\
之前的'
。您还使用了(?= ... )
的两种情况-正向超前,
这里完全不需要。
Wiktor 提出的正则表达式几乎可以,但是我会更改最后一个*
到?
,因为您只提到了一个可选姓(不是很多)。
所以我的主张是:
^[A-ZÀ-Ž][a-zà-ž]+(?:[\s'-][A-ZÀ-Ž][a-zà-ž]+)?$
说明:
^
-源字符串的开头。[A-ZÀ-Ž]
-大写字母(名称的开头)。[a-zà-ž]+
-小写字母(其余名称)的序列。(?:
-由于?
之后需要一个非捕获组。
[\s'-]
-白色字符或撇号或减号
(姓名和姓氏之间的分隔符)。[A-ZÀ-Ž][a-zà-ž]+
-姓-就像名字一样。)?
-非捕获组的结尾,可选。代替?
,
威克多(Wiktor)提出了*
,允许使用许多姓氏。$
-源字符串的结尾。因此,非捕获组将其设置为以下容器:
作为姓氏(与前面的分隔符一起使用)是可选的(?
)
可能不存在。
也许\s
应该用空格代替,因为\s
匹配
也是Tab
或'\n'
,我认为,不应使用这些字符
作为分隔符。
答案 1 :(得分:1)
您需要分别匹配大小写字母。当前,您的À-ž
欧洲字母范围包括所有大小写字母,甚至包括一些非字母。
这是您需要的范围:
大写(基本欧洲语言)
[A-Z]
[À-ÖØ-Þ]
[ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJijĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒœŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŸŹŻŽ]
小写(基本的欧洲语言)
[a-z]
[ß-öø-ÿ]
[žſāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľŀłńņňŋōŏőŕŗřśŝşšţťŧũūŭůűųŵŷźż]
您需要的模式是
/^[UPPER][lower]+(?:[\s'-][UPPER][lower]+)*$/
其中UPPER
和lower
是大写和小写字母范围/集。
所以,让我们构建模式。
var upper = '[A-ZÀ-ÖØ-ÞĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJijĴĶĹĻĽĿŁŃŅŇŊŌŎŐŒœŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶŸŹŻŽ]';
var lower = '[a-zß-öø-ÿžſāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľŀłńņňŋōŏőŕŗřśŝşšţťŧũūŭůűųŵŷźż]';
var rx = new RegExp("^" + upper + lower + "+(?:[\\s'-]" + upper + lower + "+)*$");
// Let's test
var tests = ['Test ','Test - ','Test-',' test','Test-test','TTest','Test\'test','Test','Test-Test','Test Test','Test\'Test', 'Łóźćż\'żłóźćęą'];
for (var s of tests) {
console.log(s, '=>', rx.test(s))
}
注意,还有更多可用于欧洲语言的字母。有关更多详细信息,请参见Unicode Utilities以供参考。
注意2 :如果您计划仅支持Chrome和其他兼容ECMAScript 2018的浏览器,则可以使用
console.log( // ONLY WORKS IN ECMASCRIPT 2018 COMPATIBLE JS ENVIRONMENTS
/^\p{Lu}\p{Ll}+(?:[\s'-]\p{Lu}\p{Ll}+)*$/u.test("Test'Ťĕśţ")
);
Java定义:
String pattern = "(?U)^\\p{Lu}\\p{Ll}+(?:[\\s'-]\\p{Lu}\\p{Ll}+)*$";
如果您在Java matches()
方法中使用它,请删除^
和$
,因为它们在那里多余。