【问题标题】:Inverse match with java regex与java正则表达式反向匹配
【发布时间】:2014-07-18 15:44:28
【问题描述】:

我的输入字符串是这样的:

foo 12
12 foo 123
foo 12 foo 1234
f1o2o 12345
foo 12 123456
...

我需要捕获最后一个数字:12, 123, 1234, 12345, 123456 ... 每一行都是单独处理的:

Pattern p = Pattern.compile(".*([0-9]+)$");
Matcher m = p.matcher("foo 12 123456");
m.matches()

输出:6

是否有任何形式来反转匹配?或者我应该如何更改模式以恢复最后一个数字?

【问题讨论】:

  • 制作 .* 惰性模式 p = Pattern.compile(".*?([0-9]+)$");
  • 旁注:在这种特殊情况下,您不需要正则表达式。按空格分割字符串并从结果数组中获取最后一个元素。 (仅适用于您的特定情况,使用您提供的示例数据)
  • 为什么不只是 split() 基于 \\s+ 并得到最后一个数字?

标签: java regex string-matching


【解决方案1】:

没有必要对它进行分组,只需检查数字后跟行尾。

\d+$

DEMO

示例代码:

Pattern p = Pattern.compile("\\d+$",Pattern.MULTILINE);
Matcher m = p.matcher("foo 12 123456\n12 foo 123");
while (m.find()) {
    System.out.println(m.group());
}

输出:

123456
123

Greedy 会尽可能多地查找匹配项,因此它也会捕获数字并将最后一个数字留给 [0-9]+

按照@Zack Newsham 的建议让它不贪心

DEMO


你也可以试试Positive Lookbehind

(?<=\D)\d+$

DEMO

【讨论】:

  • +1 BTW 组 1 将包含与组 0 相同的匹配项,因此实际上不需要使用 group(1) 而非 group()。此外,如果 OP 在输入中有很多行,您可以使用 MULTILINE 标志让 $ 匹配行尾,而不是字符串尾。
  • 不确定确切的要求是什么,但如果输入行可以完全由数字组成,Positive Lookbehind 将不起作用。
  • @ajb I need capture the last number: 12, 123, 1234, 12345, 123456 有意义吗。
  • @ajb 顺便说一句,除了(\d+)$,不需要任何额外的模式
  • 我对所有这些答案感到非常困惑。许多非常复杂的正则表达式来自知识渊博的用户,所以我假设我在要求中遗漏了一些东西,否则why not just this?
【解决方案2】:

将您的贪婪量词更改为不情愿的量词并使用单行方法:

String lastNum = str.replaceAll("^.*?(\\d+)\\D*$", "$1");

这会从foo 12 123456等中提取123456

【讨论】:

    猜你喜欢
    • 2020-07-02
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 2015-03-15
    • 1970-01-01
    相关资源
    最近更新 更多