我已经找到了解决方案,但是我想知道它是否可以变得更加有效或可读性更高。

我的应用程序的用户可以输入其全名,例如”Paul McCartney”,我建议以此为基础输入简短的用户名。用户名只能接受小写字母,数字和点(。)。解释一下,让我展示一下我如何做(可能会有缺陷,欢迎您改进它):

public static String formatUsername(String source) {
    return source
            .trim()
            .toLowerCase()
            .replaceAll("\\s", ".") // replace spaces with dots
            .replaceAll("[^a-z[0-9][\\.]]+", "") // remove all the rest
            .replaceAll("[\\.]{2,}", "."); // avoid sequences of dots like “.."
}


结果为paul.mccartney

现在,我还需要一个函数来告诉我某个字符串是否是可接受的用户名。检查字符很容易:

return Pattern.matches("[a-z[0-9][\\.]]+", input)


但是我想避免两个或更多个点的序列,例如paul..mccartney不好。我已经尝试过"[a-z[0-9][\\.]?]+",但是它不起作用。目前,我正在使用此:

return Pattern.matches("[a-z[0-9][\\.]]+", shortName)
    && !Pattern.compile("[\\.]{2,}").matcher(shortName).find();


但我觉得有更好的解决方案,至少更具可读性。

最佳答案

您可以使用此正则表达式进行验证:

^(?!.*\.\.)[a-z0-9.]+$


如果(?!.*\.\.)出现在任何地方,..是否定的超前断言,将使匹配失败。

在Java中:

boolean valid = input.matches("^(?!.*\\.\\.)[a-z0-9.]+$");


RegEx Demo

09-27 00:17