我正在尝试为名称执行验证器。名称可以包含字母(大小写字母),空格和不超过2个可选连字符(但不能连续)。
例如,这是正确的:
alksjdasdlfj
alsjdf ajsdfl
lkj-asdfj alsdjflj
lksaldf asldjf-jasfd-alsdjf
这是不正确的:
asjdfkl-ajsdf-asdjf-alsdjf (3 hyphens)
lasdjf--asdjfj (consecutive hyphens)
这就是我提出的:
(^[a-zA-Z]([a-zA-Z ]+\-?)*[a-zA-Z]$)|(^[a-zA-Z]*$)
但是这个正则表达式并没有将连字符的数量限制为仅出现两次。
提前感谢任何建议。
答案 0 :(得分:1)
假设单词只能有两个不能一个接一个地写的连字符,那么你要确保每个连字符后面至少有一个字母。在这种情况下,这个单词的正则表达式可能看起来像
[a-z]+(-[a-z]+){0,2} //you will need to add case-insensitive flag
表示
[a-z]+ //it starts with at least one letter
(-[a-z]+){0,2} //and have max two of words starts with `-`
所以要接受更多这样的字符串(名称),你需要像
这样的正则表达式(?i)[a-z]+(-[a-z]+){0,2}( [a-z]+(-[a-z]+){0,2})*
^ ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
| mandatory first name optional other names
+---case insensitive flag, lets `a` match also `A`
演示:
String data[] = {
"alksjdasdlfj",
"alsjdf ajsdfl",
"lkj-asdfj alsdjflj",
"lksaldf asldjf-jasfd-alsdjf",
"asjdfkl-ajsdf-asdjf-alsdjf",
"lasdjf--asdjfj", };
for (String s : data)
System.out.println(s+ " : " +
s.matches("(?i)[a-z]+(-[a-z]+){0,2}( [a-z]+(-[a-z]+){0,2})*"));
输出:
alksjdasdlfj : true
alsjdf ajsdfl : true
lkj-asdfj alsdjflj : true
lksaldf asldjf-jasfd-alsdjf : true
asjdfkl-ajsdf-asdjf-alsdjf : false
lasdjf--asdjfj : false
答案 1 :(得分:0)
这是一个想法:
^[a-zA-Z][a-zA-Z ]*(-[a-zA-Z ]+)?(-[a-zA-Z ]+)?$
你可以通过最多两次重复这组来使它更整洁:
^[a-zA-Z][a-zA-Z ]*(-[a-zA-Z ]+){0,2}$
它的工作原理如下:首先,你有一个字母和任意数量的字母/空格字符。然后有两个可选组(在括号中:(-[a-zA-Z ]+)?
),每个组都可以以连字符开头:这确保最多有两个连字符。每个连字符后面必须至少跟一个字母/空格,确保它们不连续。
如果需要,您也可以限制它,以便连字符后面没有空格。
答案 2 :(得分:0)
如果不需要RegEx,这里有一个非RegEx函数:
private bool IsValid(string str)
{
bool found = false;
bool consecutive = false;
foreach (char t in str)
{
if (!char.IsLetter(t) && t != '-' && t != ' ')
return false;
if (t == '-' && found)
{
consecutive = true;
break;
}
if (t == '-' && !found)
{
found = true;
}
if (t != '-')
found = false;
}
if (consecutive)
return false;
return str.Count(z => z == '-') <= 2;
}
使用您的示例数据进行测试,它按预期工作!
及其Java版
private boolean isValid(String str)
{
boolean found = false;
boolean consecutive = false;
for(char t : str.toCharArray())
{
if (!Character.isLetter(t) && t != '-' && t != ' ')
return false;
if (t == '-' && found)
{
consecutive = true;
break;
}
if (t == '-' && !found)
{
found = true;
}
if (t != '-')
found = false;
}
if (consecutive)
return false;
return str.chars().filter(z -> z == '-').count() <= 2;
}