在Rubular中正则表达式匹配,但在Java中不匹配。

3

我在使用java.util.regex的模式匹配器时遇到了一些正则表达式无法正常工作的问题。我有以下表达式:

(?=^.{1,6}$)(?=^\d{1,5}(,\d{1,3})?$)

我会对以下字符串进行测试匹配:

12345  (match OK)
123456 (no match)
123,12 (match OK)

当我在以下网站上测试时,它似乎完美地工作:

http://rubular.com,好的

http://www.regextester.com/,好的

http://myregextester.com/index.php,好的

然而,在我的Java程序中似乎无法匹配任何内容。此外,一个在线的Java正则表达式测试器也给出了相同的结果(没有匹配项):

http://www.regexplanet.com/advanced/java/index.html没有匹配项???

我不知道为什么我无法使它在Java中工作,但它似乎在许多其他正则表达式引擎中可以。

编辑:这是不起作用的代码。请原谅我的错别字,我无法从我的代码电脑复制/粘贴到stackoverflow。

String inputStr = "12345";
String pattern = "(?=^.{1,6}$)(?=^\\d{1,5}(,\\d{1,3})?$)";
Pattern regexp = Pattern.compile(pattern);
System.out.println("Matches? "+regexp.matcher(inputStr).matches());
System.out.println(inputStr.matches(pattern));

2
你在Java中使用什么方法进行匹配? - Joey
请展示您的(非工作中的)Java代码。 - nhahtdh
你能告诉我们你想匹配什么,并提供你在使用这个正则表达式的Java代码吗? - ioreskovic
另一件事是正则表达式进行了零长度断言 - 这意味着如果两个断言都为真,则整个正则表达式将匹配空字符串,但输入的一部分仍然被捕获在断言内的捕获组中。 - nhahtdh
3个回答

2

首先,您需要转义模式中的\。然后,如果您使用matches(),Java会尝试与整个字符串匹配,因此除非您删除第二个前瞻或在末尾添加.*,否则它将返回false。

这将在Java中产生正确的输出:

    String regex = "(?=^.{1,6}$)^\\d{1,5}(,\\d{1,3})?$";
    System.out.println("12345".matches(regex)); 
    System.out.println("123456".matches(regex)); 
    System.out.println("123,12".matches(regex));

这个表达式也是如此:

    String regex = "(?=^.{1,6}$)(?=^\\d{1,5}(,\\d{1,3})?$).*";

2

它正在正确地工作。你可能在使用matches()方法,该方法期望正则表达式匹配并消耗整个字符串。你的正则表达式没有消耗任何东西,因为它只是一些前瞻断言。在RegexPlanet网站上,查看find()列,你会看到你期望的结果。在你的Java代码中,你需要创建一个Matcher对象,这样你就可以使用它的find()方法。


谢谢大家,问题似乎就像不同的人用不同的措辞所指出的那样,即没有任何东西被消耗。在正则表达式字符串的末尾添加 “.*” 可以解决所有问题。为了完整起见,我在问题中添加了几行代码。猜想我需要多读一些并更新对正则表达式这部分的知识! - Martijn

1
这些工具的区别在于,一个尝试查找匹配项,而另一个尝试匹配整个字符串。如果您在Java中使用string.matches(regex),则对于所有输入,它都会返回false,因为您没有使用前瞻表达式来匹配整个字符串。您可以像Keppil建议的那样附加.*,或者使用Matcher类:
Pattern p = Pattern.compile(regex);
Matcher matcher = p.matcher(text);
if(matcher.find()) {
    System.out.println("Match found");
}

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