【问题标题】:How do I get a group from a partially failing Regex如何从部分失败的正则表达式中获取组
【发布时间】:2020-05-19 18:12:33
【问题描述】:

我想将一些文本传递给一个班级并让它返回一个数字和该文本的等级。

现在,如果没有给出分数,班级应该返回数字和分数,即 0.0

我现在的问题是我正在使用正则表达式(组)提取该数据。 一旦 Pattern 与整个文本不匹配,我就无法再检索数字了。

一个没有成绩的文本输入示例是:

2456272 Max Mustermann 20.02.1968
2456272 would be the number
A grade would be at the very end of the input

到目前为止我的代码:

static final String REGEX = "^(?<studentnumber>\\d{7})" // start with student number
            + ".*" // anything in between
            + "\\s+" // separated by at least one space
            + "(?<grade>10(\\.0)?|\\d([.,]\\d)?)" // 10(.0)? or one digit and optionally comma or period followed one digits.
            + "$"; // and nothing else


    private static final Pattern PATTERN = Pattern.compile(REGEX);
    private final Matcher matcher;

    /**
     * Construct a GradeFilter from a string (line).
     *
     * @param line to read
     */
    public GradeCapture(String line) {
        matcher = PATTERN.matcher(line);
        matcher.matches();
    }

    /**
     * Create a tuple. Use AbstractMap. SimpleEntry as implementing class.
     * @return the tuple.
     */
    public AbstractMap.SimpleEntry<Integer, Double> getResult() {
        if (hasResult()) {
            return new AbstractMap.SimpleEntry<>(studentId(), grade());
        }
        return new AbstractMap.SimpleEntry<>(studentId(), 0D);
    }

    /**
     * Does the line contain the required data?
     * @return whether there is a match
     */
    public boolean hasResult() {
        Integer studentId = studentId();
        Double grade = grade();
        if (studentId == null || grade == null) {
            return false;
        }
        return true;
    }
    //</editor-fold>

    /**
     * Get the grade, if any. 
     *
     * @return the grade or null
     */
    public Double grade() {
        try {
            String grade = matcher.group("grade");
            grade = grade.replaceAll(",", ".");
            return Double.parseDouble(grade);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * Get the student id, if any.
     *
     * @return the student id or null when no match.
     */
    public Integer studentId() {
        try {
            String studentnumber = matcher.group("studentnumber");
            return Integer.parseInt(studentnumber);
        } catch (Exception e) {
            return null;
        }
    }

我只想在部分匹配失败时检索匹配器组“studentnumber”。

【问题讨论】:

  • 去掉开头的^和结尾的$。它们分别匹配您输入的开始和结束。
  • edit您的问题并发布一个包含成绩的示例。
  • 遗憾的是,这不起作用,“studentnumber”组仍然为空
  • 1) 如果失败,请执行您现在的操作:2) 运行此正则表达式以获取数字:"^(?\\d{7})";
  • 我确实编辑了示例。

标签: java regex regex-group


【解决方案1】:

当成绩不存在时,您需要知道以字符串结尾的文本模式,并且该模式显然不能是\b\d+\.\d+$。在示例中,这是特定格式的日期。如果所有字符串都包含这样的日期,然后在行尾或空格后跟在行尾的等级,则可以匹配正则表达式

^(\d+).*\d{2}\.\d{2}\.\d{4}\s*(\d+\.\d+)?$

Demo(点击“Java”)

正则表达式有两个捕获组。第一个包含行首的数字字符串。如果成绩是存在的,第二个捕获组将持有它;如果不是,第二个捕获组将为空。您的 Java 代码只需将等级设置为捕获组 2 的内容(如果它不为空);否则将其设置为0.0

【讨论】:

  • 读者:在Java中,如何测试捕获组是否为null?通过测试它是否包含空字符串,就像在其他一些语言中一样?
  • 谢谢,这不是我需要的 100%,但我想缺少一些上下文。可以添加几个等级,但我只需要最后一个(相同等级不同格式)。但是稍微编辑一下你所做的就可以了。它基本上变成了这样:^(?\d{7}).*(\d{2}|\d)\.(\d{2}|\d)\.\d{4}(. *\s+(?10(\.0)?|\d([.,]\d)?)?)?$ 。数字格式和你建议的不一样,那是小数的变化。
  • 公关,很高兴你发现它有帮助。
  • tested 你的正则表达式只发现了一个小问题(测试字符串 9),可以通过在 ^(?&lt;studentnumber&gt;\d{7}) 之后添加分词来纠正。 This regex 是另一种选择,前提是等级(如果存在)跟在日期后面,中间有一个或多个空格。
猜你喜欢
  • 1970-01-01
  • 2013-11-17
  • 2014-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-06
  • 2018-04-24
  • 2011-12-30
相关资源
最近更新 更多