2013-04-04 3 views
4

J'essaie de marquer l'entrée ci-dessous en utilisant java regex. Je crois que mon expression devrait correspondre avec gourmandise aux jetons "exec" externes dans le programme ci-dessous.Greedy correspondant dans 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); 
    } 

J'attends la sortie comme

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

mais obtenir

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

Quelqu'un pourrait-il s'il vous plaît me aider à comprendre où je vais mal?

Répondre

3

Par défaut, le caractère de point . ne correspond pas aux caractères de retour à la ligne. Ici, dans ce cas, le motif "exec" ne correspondra que s'il se trouve sur la même ligne.

Vous pouvez utiliser Pattern.DOTALL de manière à harmoniser à faire sur les caractères de nouvelle ligne:

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

Alternativement (?s) peut être spécifiée, ce qui est équivalent:

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

Merci beaucoup :) – qwerty

+0

'Par défaut, Java regex Pattern ne correspond pas aux caractères de nouvelle ligne' Vous voulez probablement dire que' .' ne correspond pas à la nouvelle ligne par défaut. – nhahtdh