检查字符串是否仅包含拉丁字符?

17

您好,

我正在开发GWT应用程序,用户可以用日语输入其个人信息。但是“用户ID”和“密码”应仅包含英文字符(拉丁字母)。如何对字符串进行验证?


1
有英文字母?!?!我以为英语中的字符都来自拉丁字母表。 - Matt S.
如果他指的是ASCII字符,那我会称之为英文字符...或者美式字符。 - Tor Valamo
不要允许"ABCDEF"等等,它们绝对是法国字母。 - Arfur Narf
真正的问题是,你为什么要故意削弱密码安全性? - Arfur Narf
@ArfurNarf 嗯,这是一个13年前的问题 ;) - Ashika Umanga Umagiliya
是的,有时候我没有注意到这是一个旧问题,而一些随机的最新编辑使其重新出现。 - Arfur Narf
6个回答

40
您可以使用 String#matches() 方法,结合适当的 regex,来完成此操作。拉丁字符可以使用 \w 匹配。
boolean valid = input.matches("\\w+");

这也包括数字和下划线_。不确定是否有害。否则,您可以使用[A-Za-z]+
如果您还想涵盖变音符字符(如ä、é、ò等,这些也是拉丁字符),那么您需要先对它们进行规范化并在匹配前去除变音符号,因为没有(已记录的)正则表达式可以涵盖变音符号。
String clean = Normalizer.normalize(input, Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
boolean valid = clean.matches("\\w+");

更新: Java 中有一个未记录的正则表达式,可以匹配变音符号,即 \p{L}

boolean valid = input.matches("\\p{L}+");

以上适用于Java 1.6。


4
\p{L}已有官方文档:http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html#ubc - Joachim Sauer
1
糟糕,你是对的。我会发誓这些年来从未在API文档中看到过它。你是Sun API文档的维护者吗? - BalusC
1
没有,但是我已经阅读了那个特定的JavaDoc页面比我想承认的要多得多;-) - Joachim Sauer
1
Unicode的Letter类别\p{L}也包括很多非拉丁字母。 - Thilo
1
我认为你想要\p{script=Latin} - Thilo
w无法处理撇号,而这在爱尔兰姓氏中很常见(例如)。 - Alex White

12
public static boolean isValidISOLatin1 (String s) {
    return StandardCharsets.US_ASCII.newEncoder().canEncode(s);
} // or "ISO-8859-1" for ISO Latin 1

请参考字符集文档

我不会使用这个,因为它允许输入包含空格和控制字符(包括U+0000),这几乎肯定不会在用户名中受到欢迎。 - Joachim Sauer
使用预定义的 StandardCharsets.US_ASCII - Grigory Kislin

5
这是我的解决方案,它运行得非常出色。
public static boolean isStringContainsLatinCharactersOnly(final String iStringToCheck)
{
    return iStringToCheck.matches("^[a-zA-Z0-9.]+$");
}

3

可能有更好的方法,但您可以加载一个包含您认为可接受的字符的集合,然后将用户名/密码字段中的每个字符与该集合进行比较。

伪代码:


foreach (character in username)
{
    if !allowedCharacters.contains(character)
    {
        throw exception
    }
}

2

对于这样简单的事情,我会使用正则表达式。

private static final Pattern p = Pattern.compile("\\p{Alpha}+");

static boolean isValid(String input) {
  Matcher m = p.matcher(input);
  return m.matches();
}

还有其他预定义的类别,例如\w,可能更适合。


1

我成功地使用了用户232624、Joachim SauerTvaroh的答案的组合:

static CharsetEncoder asciiEncoder = Charset.forName("US-ASCII"); // or "ISO-8859-1" for ISO Latin 1

boolean isValid(String input) {    
    return Character.isLetter(ch) && asciiEncoder.canEncode(username);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接