通过正则表达式验证连字符

时间:2014-06-09 23:33:14

标签: java regex

我正在尝试为名称执行验证器。名称可以包含字母(大小写字母),空格和不超过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]*$)

但是这个正则表达式并没有将连字符的数量限制为仅出现两次。

提前感谢任何建议。

3 个答案:

答案 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;
}