2009-04-22 9 views
3

je reçois une chaîne à partir d'une liste de tableau:Question sur Java regex

array.get(0).toString() 

donne TITLE = "blabla"

Je veux la chaîne blabla, donc j'essayer ceci:

Pattern p = Pattern.compile("(\".*\")"); 
Matcher m = p.matcher(array.get(0).toString()); 
System.out.println("Title : " + m.group(0)); 

Cela ne fonctionne pas: java.lang.IllegalStateException: No match found

J'essaie aussi:

Pattern p = Pattern.compile("\".*\""); 
Pattern p = Pattern.compile("\".*\""); 
Pattern p = Pattern.compile("\\\".*\\\""); 

Rien ne correspond à mon programme, mais tous les modèles travaillent sur http://www.fileformat.info/tool/regex.htm

Toute idée? Merci d'avance.

Répondre

8

Quelques points:

Javadoc pour Matcher#group états:

IllegalStateException - Si aucune correspondance n'a été tenté, ou si l'opération de correspondance précédente a échoué

C'est , avant d'utiliser le groupe, vous devez d'abord utiliser m.matches (pour faire correspondre la séquence entière), ou m.find (pour correspondre à une sous-séquence).

Deuxièmement, vous voulez réellement m.group(1), puisque m.group(0) est le modèle entier. En fait, ce n'est pas si important ici puisque l'expression rationnelle en question commence et finit avec les parenthèses de capture, de sorte que le groupe (0) est la même chaîne que le groupe (1), mais cela aurait de l'importance si votre expression rationnelle comme: "TITLE = (\".*\")"

code Exemple:

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

import org.junit.Test; 

@SuppressWarnings("serial") 
public class MatcherTest { 

    @Test(expected = IllegalStateException.class) 
    public void testIllegalState() { 
     List<String> array = new ArrayList<String>() {{ add("Title: \"blah\""); }}; 
     Pattern p = Pattern.compile("(\".*\")"); 
     Matcher m = p.matcher(array.get(0).toString()); 
     System.out.println("Title : " + m.group(0)); 
    } 

    @Test 
    public void testLegal() { 
     List<String> array = new ArrayList<String>() {{ add("Title: \"blah\""); }}; 
     Pattern p = Pattern.compile("(\".*\")"); 
     Matcher m = p.matcher(array.get(0).toString()); 
     if (m.find()) { 
      System.out.println("Title : " + m.group(1)); 
     } 
    } 
} 
+0

"Votre expression rationnelle doit correspondre à la chaîne entière" - c'est la différence entre 'matches()' et 'find()', donc vos deux premiers points ne sont pas aussi distincts que vous semblez l'impliquer. – araqnid

+0

, espérons clarifié – toolkit

0

êtes-vous, y compris les guillemets doubles (") dans la chaîne?

Tous vos regex ont échappé « s et ne correspondra si la chaîne dans la liste comprend des caractères doubles guillemets.

6

Vous devez d'abord appeler le find() ou le matches() sur l'instance de Matcher: ils exécutent en fait l'expression régulière et retournent si elle correspond ou non. Et puis seulement si cela correspond, vous pouvez appeler les méthodes pour obtenir les groupes de correspondance.

+0

Dans ce cas, il est FIND() que vous voulez appeler. –

+0

C'est vrai. Parce que c'est une supposition douteuse que si vous avez compilé un motif et que vous avez fait un "Matcher" pour une chaîne donnée, vous voulez toujours * trouver * quelque chose dans cette chaîne. (Si vous voulez seulement savoir si quelque chose * correspond * au motif, je ne vois pas pourquoi vous avez besoin d'un * Matcher * et que le Motif ne peut pas vous le dire lui-même.) Sauver le monde par la verbosité ... – Axeman

+0

Si vous voulez un code plus court, vous pouvez simplement écrire Pattern.matches ("regex", entrée). Si vous voulez que le motif soit compilé une seule fois pour plusieurs matches, vous devez en faire plus, oui. Vous semblez vous plaindre qu'il n'y a pas de méthode d'instance de commodité pattern.matches (CharSequence). Après tout, vous pouvez appeler matcher.find() plusieurs fois pour trouver plusieurs correspondances, ce qui est assez différent de faire du matcher.matches() ou matcher.lookingAt(). – araqnid