【问题标题】:Java regular expression to check if there is at least one letterJava正则表达式检查是否至少有一个字母
【发布时间】:2017-09-11 23:33:10
【问题描述】:

我在 SO 和 Web 上发现了很多关于这个主题的变体,但大多数(如果不是全部)要求至少一个字母和一个数字。我需要至少一封信。 我试过了,但我没有做对,我需要的是字符串只包含字母、字母+数字(任何顺序)、破折号和空格是允许的,但不能在字符串的开头或结尾。这是它现在的样子:

protected static final String PATTERN = "[\u00C0-\u017Fa-zA-Z0-9']+([- ][\u00C0-\u017Fa-zA-Z0-9']+)*";

    public static void main(String[] args) {

        String name;

        //name = "Street"; // allowed
        //name = "Some-Street"; // allowed
        //name = "Street "; // not allowed
        //name = " Street"; // not allowed
        //name = "Street-"; // not allowed
        //name = "-Street"; // not allowed
        //name = "Street"; // allowed
        //name = "1 st street"; // allowed
        //name = "street 5"; // allowed
        name = "111"; // NOT allowed

        if (!Pattern.matches(PATTERN, name)) {
            System.out.println("ERROR!");
        } else System.out.println("OK!");
    }
}

如何添加检查是否至少有一个字符?

无论是在开头还是结尾,或者它与数字之间是否有空格或破折号。必须至少有一个字符。

【问题讨论】:

  • 您想要至少 1 个字符还是 1 个字母?那是非常不同的。
  • 如果你不允许开头或结尾的空格,在保存之前trim()字符串不是更方便用户吗?空间通常不可见,这会让用户感到困惑和沮丧。
  • "A" 是有效输入吗?
  • trim() 可用于前端或后端。后端开发对于字符串格式化会更好,因为用户无法将其关闭。你绝对应该在后端清理你的字符串,而不是依赖任何基于前端的东西。

标签: java regex


【解决方案1】:

你可以使用这个正则表达式来解决你的问题:

^(?=.*\pL)[\pL\pN]+(?:[ -]+[\pL\pN]+)*$

RegEx Demo

对于 Java 使用:

final String regex = "^(?=.*\\pL)[\\pL\\pN]+(?:[ -]+[\\pL\\pN]+)*$";

RegEx 拆分:

  • ^:开始
  • (?=.*\pL):使用前瞻确保我们在某处至少有一个 unicode 字母
  • [\pL\pN]+:匹配一个或多个unicode字母或unicode数字
  • (?:: 非捕获组开始
    • [ -]+:匹配一个或多个空格或连字符
    • [\pL\pN]+:匹配一个或多个unicode字母或unicode数字
  • )*:非捕获组结束。 * 表示该组中的零个或多个。
  • $:结束

【讨论】:

    【解决方案2】:

    如果我理解正确,根据您的介绍,您有以下条件:

    • 至少 1 个字母
    • 可以包含数字(但前提是满足前面的条件)
    • 只有不在字符串开头或结尾的破折号和空格才允许使用

    根据这些条件,以下正则表达式将起作用:

    ^(?![ -]|\d+$)[[:alnum:] -]+(?<![ -])$
    

    要查看此正则表达式的使用情况,请单击 this 链接。
    此正则表达式的工作方式如下:

    • 确保字符串不以连字符- 或空格 开头
    • 确保字符串不只由数字组成
    • 确保字符串包含一个到无限个字母数字字符
    • 确保字符串不以连字符- 或空格 结尾

    这将为您提供以下匹配项

    Street
    Some-Street
    Street
    1 st street
    street 5
    

    正则表达式将无法匹配以下字符串(根据您的示例)

    Street 
     Street
    Street-
    -Street
    111
    

    编辑

    消极的lookbehinds有时会导致某些语言(如java)出现问题。

    下面是我之前的正则表达式的改编版本,它使用负前瞻而不是负后瞻来确保字符串不以连字符 - 或空格 结尾。

    ^(?![ -]|\d+$)(?:(?![ -]$)[\pL\pN -])+$
    

    你可以看到这个正则表达式正在使用here

    【讨论】:

    • @NenadBulatovic 显然 java 不能很好地处理负面的后视。我已经编辑了我的正则表达式以使用负前瞻而不是负后瞻来确保字符串不以连字符或空格结尾
    【解决方案3】:

    按照正则表达式完成工作:

    (?=.*[[:alpha:]])[[:alnum:]]{1}[[:alnum:] -]*[[:alnum:]]{1}
    
    • (?=.*[[:alpha:]]) 部分保证字母字符 [A-Za-z] 存在于单词中。

    • [[:alnum:]]{1} 部分保证字符串以字母数字开头 字符 [A-Za-z0-9]

    • [[:alnum:] -]* 字母数字字符、空格和破折号字符 可能存在于此。

    • [[:alnum:]]{1} 部分保证字符串以字母数字结尾 字符 [A-Za-z0-9]

    观看直播https://regex101.com/r/V0lesF/1

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多