2016-12-13 6 views
-1

Предположим, что я хочу создать очень большое регулярное выражение с группами захвата во время выполнения на основе пользовательских решений.Java regex - определить, какая группа захвата была сопоставлена ​​и подсчеты числа

Простой пример:

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

public class Test {  
    static boolean findTag, findWordA, findOtherWord, findWordX; 

    static final String TAG = "(<[^>]+>)"; 
    static final String WORD_A = "(wordA)"; 
    static final String OTHER_WORD = "(anotherword)"; 
    static final String WORD_X = "(wordX)"; 

    static int tagCount = 0; 
    static int wordACount = 0; 
    static int otherWordCount = 0; 
    static int wordXCount = 0; 

    public static void main(String[] args) { 
     // Boolean options that will be supplied by the user 
     // make them all true in this example 
     findTag = true; 
     findWordA = true; 
     findOtherWord = true; 
     findWordX = true; 

     String input = "<b>this is an <i>input</i> string that contains wordX, wordX, anotherword and wordA</b>"; 

     StringBuilder regex = new StringBuilder(); 

     if (findTag) 
      regex.append(TAG + "|"); 

     if (findWordA) 
      regex.append(WORD_A + "|"); 

     if (findOtherWord) 
      regex.append(OTHER_WORD + "|"); 

     if (findWordX) 
      regex.append(WORD_X + "|"); 

     if (regex.length() > 0) { 
      regex.setLength(regex.length() - 1); 
      Pattern pattern = Pattern.compile(regex.toString()); 

      System.out.println("\nWHOLE REGEX: " + regex.toString()); 
      System.out.println("\nINPUT STRING: " + input); 

      Matcher matcher = pattern.matcher(input); 

      while (matcher.find()) { 
       // only way I know of to find out which group was matched: 
       if (matcher.group(1) != null) tagCount++; 
       if (matcher.group(2) != null) wordACount++; 
       if (matcher.group(3) != null) otherWordCount++; 
       if (matcher.group(4) != null) wordXCount++; 
      } 

      System.out.println(); 
      System.out.println("Group1 matches: " + tagCount); 
      System.out.println("Group2 matches: " + wordACount); 
      System.out.println("Group3 matches: " + otherWordCount); 
      System.out.println("Group4 matches: " + wordXCount); 

     } else { 
      System.out.println("No regex to build."); 
     } 
    } 
} 

Проблема заключается в том, что я могу рассчитывать только матчи каждой группы только тогда, когда я заранее знать, какое регулярное выражение/группа пользователь хочет найти.

Обратите внимание, что полное регулярное выражение будет содержать намного больше групп захвата, и они будут более сложными.

Как определить, какая группа захвата была сопоставлена, чтобы я мог подсчитывать события каждой группы, не зная заранее, какие группы пользователь хочет найти?

+0

может быть, очевидный ответ, но вы понимаете, что вы можете использовать 'groupCount()', чтобы определить количество групп? –

+1

Не имеет отношения, но 'StringBuilder' используется точно, чтобы избежать конкатенации строк (что создает дополнительные' StringBuilder 'для каждого выражения конкатенации). Поэтому вместо 'regex.append (TAG +" | ");' use 'regex.append (TAG) .append (" | ");'. – Pshemo

+0

@PatrickParker количество групп недостаточно, мне нужно знать _which_ группы для подсчета. – AndroidX

ответ

0

построить регулярное выражение к используемому named groups:

(?<tag>wordA)|(?<wordx>wordX)|(?<anotherword>anotherword) 
+0

Это работает ... из любопытства заключается в том, что единственный способ сделать это? – AndroidX

+0

, так как это не действительно «шаблон», а более простой тест равенства, я не знаю, что здесь требуется даже регулярное выражение. – sweaver2112

+0

Я использую шаблоны ... приведенный выше код просто предназначен для простого примера. – AndroidX