正则表达式在 String.matches() 中不起作用

Posted

技术标签:

【中文标题】正则表达式在 String.matches() 中不起作用【英文标题】:Regex doesn't work in String.matches() 【发布时间】:2012-02-13 22:55:38 【问题描述】:

我有一小段代码

String[] words = "apf","hum_","dkoe","12f";
for(String s:words)

    if(s.matches("[a-z]"))
    
        System.out.println(s);
    

应该打印

dkoe

但它什么也没打印!!

【问题讨论】:

Java 的 matches 在正则表达式的开头放置一个 ^ 并在结尾放置一个 $ 。所以 matches("[a-z]") 实际上会寻找 /^[a-z]$/ 。 是的@Robino,你是绝对正确的。 当然,如果您希望matches 查找[a-z] 的任何出现,那么它应该匹配它们吗?我不指望matches 会根据正则表达式单独检查每个字符。 @Toru 在 String.Matches 的 java 文档页面上 - 还有哪里? “java字符串匹配文档”的随意谷歌显示,在顶部结果中,短语“str.matches(regex)产生与表达式完全相同的结果”。重要的词是“确切地”。 @PhilHibbs 是的,这也是我的期望! 【参考方案1】:

[a-z] 匹配 a 和 z 之间的 单个 字符。因此,例如,如果您的字符串只是 "d",那么它就会匹配并被打印出来。

您需要将您的正则表达式更改为[a-z]+ 以匹配一个或多个字符。

【讨论】:

当然匹配单个字符,这就是正则表达式的作用!然而,尚不清楚(也不应该是这种情况!)是java将前缀^和后缀$放在提供的正则表达式周围,不必要地改变它并产生奇怪的错误。他们不应该这样做,因为这不是最初的正则表达式的意思。【参考方案2】:

您的正则表达式 [a-z]dkoe 不匹配,因为它只匹配长度为 1 的字符串。使用类似 [a-z]+ 的内容。

【讨论】:

【参考方案3】:

欢迎使用 Java 错误命名的 .matches() 方法...它会尝试匹配所有输入。不幸的是,其他语言也纷纷效仿:(

如果您想查看正则表达式是否匹配输入文本,请使用匹配器的PatternMatcher.find() 方法:

Pattern p = Pattern.compile("[a-z]");
Matcher m = p.matcher(inputstring);
if (m.find())
    // match

如果您确实想要查看输入是否只有小写字母,您可以使用.matches(),但您需要匹配一个或多个字符:将+ 附加到您的字符类,如@987654330 @。或者使用^[a-z]+$.find()

【讨论】:

我在网上找到了 100 多个不完整的教程。找不到好的。你有什么建议吗? 感谢@fge 解释.matches()。可能你知道为什么.find() 在this example 中运行如此缓慢吗? 你说的其他语言纷纷效仿是什么意思?据我所知,只有 C++ 有一组等效的方法 - regex_searchregex_match。在 Python 中,re.match 仅将匹配项锚定在字符串的开头(就好像它是 \Apattern)并且 Python 3.x 有一个很好的 .fullmatch() 方法。在 JS、Go、php 和 .NET 中,没有隐式锚定匹配的正则表达式方法。 ElasticSearch、XML Schema 和 html5/Validators Angular 模式总是默认锚定。在 Swift/Objective C 中,有一种方法可以在开头使用选项锚定模式。 那种感觉当你浪费时间想知道你的正则表达式有什么问题并最终得到这个 SO 答案时意识到你很久以前就已经支持它了...... 这是真的 String#matches() 默认匹配整个字符串,但 "123abc".matches("^[0-9]+.*$")"123abc".matches("[0-9]+.*") 也可以【参考方案4】:

java 的正则表达式实现尝试匹配整个字符串

这与 perl 正则表达式不同,后者试图找到匹配的部分

如果您想查找只有小写字符的字符串,请使用模式[a-z]+

如果要查找至少包含一个小写字符的字符串,请使用模式.*[a-z].*

【讨论】:

更多信息here 为什么是not documented?!【参考方案5】:

String.matches 返回 整个 字符串是否与正则表达式匹配,而不仅仅是任何子字符串。

【讨论】:

有些可悲的现实是你是对的。我真的不知道他们为什么这样做。【参考方案6】:

二手

String[] words = "apf","hum_","dkoe","12f";
    for(String s:words)
    
        if(s.matches("[a-z]+"))
        
            System.out.println(s);
        
    

【讨论】:

【参考方案7】:

您可以通过以下方式使您的模式不区分大小写:

Pattern p = Pattern.compile("[a-z]+", Pattern.CASE_INSENSITIVE);

【讨论】:

【参考方案8】:

我曾经遇到过同样的问题:

Pattern ptr = Pattern.compile("^[a-zA-Z][\\']?[a-zA-Z\\s]+$");

以上失败!

Pattern ptr = Pattern.compile("(^[a-zA-Z][\\']?[a-zA-Z\\s]+$)");

以上内容适用于 () 中的模式。

【讨论】:

【参考方案9】:

您必须在模式中至少放置一个捕获() 才能匹配,并且正确的模式如下:

String[] words = "apf","hum_","dkoe","12f";
for(String s:words)

    if(s.matches("(^[a-z]+$)"))
    
        System.out.println(s);
    

【讨论】:

括号没有改变任何东西。 @Touniouk 不带括号 matches 没有任何输出。

以上是关于正则表达式在 String.matches() 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

关于String的matches方法

Java String.matches正则表达式与OR管道[重复]

string.matches(regex) 返回 false,虽然我认为它应该是 true

使用正则表达式匹配多行文本

带有正则表达式的代码似乎无缘无故地结束

Java正则表达式忽略/注释掉正则表达式的一部分[重复]