2013-04-04 2 views
4

Я пытаюсь tokenize ввода ниже с помощью java regex. Я считаю, что мое выражение должно с жадностью сопоставлять внешние теги «exec» в приведенной ниже программе.Greedy matching в regex (java)

@Test 
    public void test(){ 
     String s = "exec(\n" + 
       " \"command #1\"\n" + 
       " ,\"* * * * *\" //cron string\n" + 
       " ,\"false\" eq exec(\"command #3\")) //condition\n" + 
       ")\n" + 
       "\n" + //split here 
       "exec(\n" + 
       " \"command #2\" \n" + 
       " ,\"exec(\"command #4\") //condition\n" + 
       ");"; 
     List<String> matches = new ArrayList<String>(); 
     Pattern pattern = Pattern.compile("exec\\s*\\(.*\\)"); 
     Matcher matcher = pattern.matcher(s); 
     while (matcher.find()) { 
      matches.add(matcher.group()); 
     } 
     System.out.println(matches); 
    } 

Я ожидаю выход как

[exec(
    "command #1" 
    ,"* * * * *" //cron string 
    ,"false" eq exec("command #3")) //condition 
),exec(
    "command #2" 
    ,"exec("command #4") //condition 
);] 

но получить

[exec("command #3")), exec("command #4")] 

Может кто-нибудь, пожалуйста, помогите мне понять, где я неправильно?

ответ

3

По умолчанию символ точки . не соответствует символам новой строки. Здесь в этом случае шаблон «exec» будет соответствовать только в том случае, если он встречается в той же строке.

Вы можете использовать Pattern.DOTALL, чтобы сопоставления, должно быть сделано на новой строки символов:

Pattern.compile("exec\\s*\\(.*\\)", Pattern.DOTALL); 

(?s) В качестве альтернативы может быть указано, что эквивалентно:

Pattern.compile("(?s)exec\\s*\\(.*\\)"); 
+0

спасибо так много :) – qwerty

+0

'По умолчанию шаблон шаблона Java regex не совпадает с символами новой строки. Вероятно, вы имеете в виду, что' .' по умолчанию не соответствует новой строке. – nhahtdh