【问题标题】:Regex creating an empty group?正则表达式创建一个空组?
【发布时间】:2013-10-13 21:53:04
【问题描述】:

我已经编写了一个 rexeg 字符串来将日志解析为一组组,但是当存在日志的可选部分时,它会创建一个空组。我在正则表达式中使用? 将部分标记为可选,但它似乎仍然创建了一个空组。

这是我尝试过的两个正则表达式;

([0-9]{2}:[0-9]{2}\.[0-9]{2}) - (DMG|KILL):[ ]+(.*?)\[(.*?)\] (?:damaged|killed) (.*?) \[(.*?)\](?: for (\d{0,9}) dmg)?

([0-9]{2}:[0-9]{2}\.[0-9]{2}) - (DMG|KILL):[ ]+(.*?)\[(.*?)\] (?:damaged|killed) (.*?) \[(.*?)\](?: for (\d{0,9})? dmg)?

我的第二个正则表达式在(\d{0,9}) 的末尾有一个问号,因为我认为这可能会创建空组,但似乎并非如此。我正在按照以下内容解析一个字符串;

00:00.00 - DMG:     Player [group] damaged Victim [group] for 130 dmg
00:00.00 - KILL:     Player [group] killed Victim [group]

在解析最后一行(不是for X damage)时,最后会创建一个空组。

我为可怕的正则表达式道歉。


感谢 cmets 部分中的@Sniffer,我的正则表达式工作正常。可以看到 here 它按预期工作,但是当实现到我的应用程序中时,它没有。

在我的应用程序中,matcher.group(7)(最后一组)位于“KILL”行(不包含“dmg”的行返回 null,并且 matcher.groupCount() 返回 7 而不是 6,这意味着它找到了最后是空组。我的正则表达式如下;

private static final Pattern match = Pattern.compile("([0-9]{2}:[0-9]{2}\\.[0-9]{2}) - (DMG|KILL):[ \t]+(.*?)\\[(.*?)\\] (?:damaged|killed) (.*?) \\[(.*?)\\](?: for (\\d{0,9}) dmg)?");

这是我用来匹配模式的代码;

Matcher matcher = DamageEvent.match.matcher(tLine);

if (matcher.matches())
{
    int matches = matcher.groupCount();
    if (matches < 6 || matches > 7)
    {
        System.err.println("Invalid line: " + tLine);
        return null;
    }
    String time = matcher.group(1);
    String type = matcher.group(2);
    String attackerName = matcher.group(3);
    String attackerGroupString = matcher.group(4);
    String victimName = matcher.group(5);
    String victimGroupString = matcher.group(6);
    String damage = "0";

    System.out.println(matches);

    if (matches == 7) // This results as 'true'
    {
        damage = matcher.group(7); // Damage is set to null :(
    }

}

【问题讨论】:

  • 您使用的语言或工具?
  • 最后我将使用 Java 的正则表达式模式和匹配器,但现在我正在查看使用 this tool 创建的组。
  • 我已经测试了你的正则表达式here,一切正常。
  • 哦,哇,那一定是个没用的正则表达式测试器,或者只是工作方式不同的测试器。谢谢,我猜案子已经结案了!
  • 在将 matcher.group(7) 分配给“损坏”变量之前,您能否检查一下它是否为空?

标签: regex parsing grouping


【解决方案1】:

这是设计使然,例如每Javadoc

如果匹配成功,但指定的组未能匹配输入序列的任何部分,则返回 null

所以下面example

    Matcher m1 = Pattern.compile("(t1)(t2)?(t3)").matcher("t1t3");
    if(m1.matches()) {
        for(int g=1;g<=m1.groupCount();g++){
            System.out.println("Group "+g+": "+m1.group(g));
        }
    }
    System.out.println("--------------");
    Matcher m2 = Pattern.compile("(t1)()(t3)").matcher("t1t3");
    if(m2.matches()) {
        for(int g=1;g<=m2.groupCount();g++){
            System.out.println("Group "+g+": "+m2.group(g));
        }
    }

将输出:

Group 1: t1
Group 2: null
Group 3: t3
--------------
Group 1: t1
Group 2: 
Group 3: t3

【讨论】:

  • 有没有办法让它忽略一个可选组?还是我只检查 null?
  • 我看到如果组中没有任何匹配项,则返回 null 是 group() 设计的一部分,我想这没问题,我可以按照 @Ashalynd 的建议检查 null
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-02
  • 1970-01-01
  • 1970-01-01
  • 2011-08-26
相关资源
最近更新 更多