2013-10-13 7 views
0

Я написал строку rexeg для анализа журнала в набор групп, однако он создает пустую группу, когда присутствует необязательный раздел журнала. Я пометил раздел необязательным, используя ? в regex, но он все еще создает пустую группу.Regex создает пустую группу?

Вот два регулярных выражения, которые я пробовал;

([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) пустая группа создается в конце.

Извиняюсь за чудовищное регулярное выражение.


Было показано, что мое регулярное выражение работает отлично, спасибо @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 :(
    } 

} 
+0

Язык или инструмент, который вы используете? –

+0

В конце я буду использовать шаблон и шаблон Java Regex, но сейчас я просматриваю группы, созданные с помощью этого инструмента (http://www.softlion.com/webTools/RegExpTest/default.aspx). –

+0

Я проверил ваше регулярное выражение [** здесь **] (http://regex101.com/r/wS2cL9), и все работает нормально. –

ответ

4

Это сделано, например, в 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 
+1

Есть ли способ заставить его игнорировать необязательную группу? Или я просто проверяю на нуль? –

+0

Я вижу, что это часть дизайна группы(), чтобы вернуть значение null, если в группе ничего не сопоставлено, и я думаю, что это нормально, я просто могу проверить «null», как предложил @Ashalynd. –

Смежные вопросы