正则表达式检查字符串是否包含非数字字符失败

4
为什么会失败?
String n = "h107";
if (n.matches("\\D+")) {
  System.out.println("non digit in it");
}

我为此彻夜难眠,但仍然没有弄懂。 现在我有一个解决方案:

if (n.matches(".*\\D+.*")) {

但是在我的理解中(也许是缺乏知识),第一个也应该匹配。因为如果它必须匹配完整的字符串,那么'^'字符表示行开头有什么意义呢。


很难不回答说这只是另一个愚蠢的Java API… - Denys Séguret
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - fge
@fge,这个命名有误,而且设计选择很薄弱。如果在这里使用标准的正则表达式约定,我们可以决定何时匹配整个字符串而不必使用繁琐的Pattern API 进行简单检查。 - Denys Séguret
2个回答

7
这是“matches()”方法经常出现的问题:它的名称不准确。它并不执行正则表达式匹配。而且问题在于,即使其他语言也会犯这种错误(例如Python)。
问题在于它会尝试匹配您整个输入内容。
相反,可以使用PatternMatcher.find().find() 会真正执行正则表达式匹配,即查找与输入中任何位置匹配的文本)来解决。
private static final Pattern NONDIGIT = Pattern.compile("\\D");

// in code
if (NONDIGIT.matcher(n).find())
    // there is a non digit

事实上,您应该使用PatternString.matches()会每次重新编译模式。使用Pattern只需要编译一次即可。

1
Java的语法很好,但sun制作的api完全是垃圾。 - clankill3r
嘿,一旦你掌握了它,你就会忘记它有多“古怪”了 ;) 总之,考虑到所有因素,Java的正则表达式引擎非常好。PatternMatcher之间的逻辑分离也很合理。然而,是的,我确实希望方法名能更好一些。就像很多人一样... - fge

2

String.matches会在整个字符串与模式匹配时返回true。只需将您的正则表达式更改为\d+,如果整个字符串由数字组成,则返回true:

String n = "h107";
if (!n.matches("\\d+")) {
     System.out.println("non digit in it");
}

与使用“Pattern”相比,这种解决方案的成本相当高。 - fge

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