【问题标题】:Java RegEx: How to extract just the variable portion of a pattern matchJava RegEx:如何仅提取模式匹配的变量部分
【发布时间】:2012-10-08 18:59:49
【问题描述】:

假设您有以下字符串:

id: 1 name: Joe age: 27 id: 2 name: Mary age:22

您想提取“age:”之后的每个标记,而不是字符串“age:”本身。

所以我希望我的 Matchergroup() 返回 27 和 22,而不是“年龄:27”和“年龄:22”

有没有办法在 Java Regex 语法中指定这条指令,这似乎与我在 Perl 中学习 Regex 基础的方式大不相同?

这是我的代码:

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class RegExTest 
{
    public static void main(String[] args) 
    {
        Pattern namePtrn = Pattern.compile("age: *\\w*");

        String data = "id: 1 name: Joe age:27 id: 2 name: Mary age:22";

        Matcher nameMtchr = namePtrn.matcher(data);

        while(nameMtchr.find())
        {
            String find = nameMtchr.group();

            System.out.println ("\t" + find);
        }
    }
}

在 Perl 中,我可以使用 {} 来限制我想要提取的模式部分

while($text =~ m/(age:{\w+})/g)
{
      my $find = $1;

      if($find)
      {
          print "\nFIND = ".$find;
      }
}

会返回

FIND = 27
FIND = 22

如果我把 {} 放在年龄上

while($text =~ m/({age:\w+})/g)

它会返回

FIND = age: 27
FIND = age:22

所以我正在寻找类似 Perl 的 {} 但在 Java 中的东西。

【问题讨论】:

  • 标准捕获组(关键字)就是你所得到的;比较:m/age:(\w+)/g ..
  • (请阅读详细手册了解如何访问 捕获组 - 关键字!- 在 Java 中。就像 Perl 一样,有一种特殊的方法可以访问特定组:例如$1$&。)
  • 什么!? Perl 使用花括号来表示捕获组?
  • Perl uses curly braces as quantifiers;不适用于捕获组。
  • 可能是因为你没有正确阅读超过一半的答案。

标签: java regex


【解决方案1】:

如果您使用Matcher.group(1) 而不是Matcher.group(),则可以捕获减去“年龄:”的模式:

String data = "id: 1 name: Joe age:27 id: 2 name: Mary age:22";
Pattern namePtrn = Pattern.compile("age:(\\w+)");
Matcher nameMtchr = namePtrn.matcher(data);

while (nameMtchr.find()) {
   String find = nameMtchr.group(1);
   System.out.println("\t" + find);
}

【讨论】:

  • 正如附加注释 \w 用于匹配任何单词字符并且 \ 需要转义,因此附加 \ 使其成为 \\w 并且 + 表示出现 1 次或多次。弯括号表示其中的内容是一个组。
【解决方案2】:

试试:

age:\s*(\d+)

匹配“年龄:”,后跟任意数量的空格,后跟一位或多位数字。数字(数值)被捕获在第一组中。

如果您想支持负年龄(即 -1 表示“年龄未知”或其他内容),您可以使用:

age:\s*(-?\d+)

这将匹配“年龄:”,后跟任意数量的空格,后跟零或一个减号,后跟一位或多位数字。数字和可选的减号(数值)被捕获在第一组中。

如果您不确定如何让捕获组工作,consult this question which has a few examples.

【讨论】:

  • 不,那没有。顺便说一句,你需要使用双\,否则Java将无法编译
  • @foampile 发布的示例显示了正则表达式 value,而不是字符串文字(没有“s”)。此外,“did not do”是一个近乎无用的语句. 一个更好的可能是:“我仍然不知道如何访问捕获组。”
  • “没有做”意味着我把它放在我的代码中,它没有返回我在 OP 中要求的内容
  • @foampile:你必须得到组,而不是整个匹配的模式。
【解决方案3】:

使用非转义括号:

Pattern namePtrn = Pattern.compile("age: *(\\w*)");

这会将它放在 Matcher 的第一个捕获组中。

【讨论】:

  • 那也没有。在值之前输出“age:”
  • @foampile ..因为捕获组仍未被使用 - 推测整个 整个匹配 捕获仍在使用,而不是特定捕获组。当然,这两篇文章都没有显示如何到达 特定 捕获组。
  • name: 应该是正则表达式中的age:
  • OP 明确规定了输出应该是什么:27 和 22,而不是年龄:27 和年龄:22
  • @foampile 同样,正则表达式是有效的并显示了捕获组的使用(即使有错字),它的用法是不正确。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-16
  • 1970-01-01
  • 1970-01-01
  • 2017-10-15
  • 1970-01-01
  • 2021-08-05
  • 2011-12-10
相关资源
最近更新 更多