2010-07-04 4 views
1
public class PatternTest { 
    public static void main(String[] args) { 
    System.out.println("117_117_0009v0_172_5738_5740".matches("^([0-9_]+v._.)")); 
    } 
} 

Ce programme imprime "faux". Quelle?!Quoi de neuf avec cette expression régulière ne correspond pas?

Je me attends à correspondre au préfixe de la chaîne: « 117_117_0009v0_1 »

Je sais ce genre de choses, vraiment que je fais ... mais pour la vie de moi, que je suis les yeux fixés sur ce pendant 20 minutes et j'ai essayé toutes les variations auxquelles je peux penser et il me manque évidemment quelque chose de simple et évident ici. En espérant que les nombreux yeux de SO puissent le choisir pour moi avant que je perde la tête à ce sujet.

Merci!


La version finale de travail a pris fin comme:

String text = "117_117_0009v0_172_5738_5740"; 
String regex = "[0-9_]+v._."; 

Pattern p = Pattern.compile(regex); 

Mather m = p.matcher(text); 
if (m.lookingAt()) { 
    System.out.println(m.group()); 
} 

Une découverte non évidente/rappel pour moi qui avant d'accéder à des groupes de matcher, l'un des matches() regarderLes() ou trouver() doit être appelé. Si ce n'est pas une exception IllegalStateException est lancée avec le message inutile "Match introuvable". Malgré cela, groupCount() retournera non-zéro, mais il ment. Ne le croyez pas.

J'ai oublié à quel point cette API est moche. Argh ...

+0

il indique le nombre d'ensembles de parenthèses de capture présents dans l'expression rationnelle. Il ne dit rien de ce qui a été réellement apparié, bien que de nombreuses personnes l'interprètent de cette façon au début. –

Répondre

3

par défaut Java colle dans les opérateurs ^ et $, donc quelque chose comme cela devrait fonctionner:

public class PatternTest { 
    public static void main(String[] args) { 
    System.out.println("117_117_0009v0_172_5738_5740".matches("^([0-9_]+v._.).*$")); 
    } 
} 

retours:

vrai

contenu du match:

117_117_0009v0_1 

Ceci est le code que j'utilisé pour extraire le match:

 Pattern p = Pattern.compile("^([0-9_]+v._.).*$"); 
     String str = "117_117_0009v0_172_5738_5740"; 

     Matcher m = p.matcher(str); 
     if (m.matches()) 
     { 
      System.out.println(m.group(1)); 
     } 
+0

Ok. question stupide mais comment avez-vous accédé au contenu du match? Je me suis retrouvé avec le même modèle que vous avez là-bas, ce qui est vrai pour le code que vous montrez. Mais j'ai essayé .group() .group (0), etc ... et tous lancent une exception IllegalStateException ("No Match Found"). Pourtant, groupCount() renvoie 1?!?! –

+0

Groupes d'expressions régulières commencent par 1 et non 0, je sais que cela peut être source de confusion jusqu'à ce que vous obtenez le coup :) – npinti

+0

Je connais cette partie. Le groupe 0 doit être l'intégralité de la section correspondante. Le groupe 1 et les versions supérieures correspondent au texte correspondant de tous les groupes de capture du modèle. Les docs disent que le groupe appelant (n) est valide pour tout n> = groupCount(). J'ai finalement compris que vous devez d'abord appeler find() avant d'essayer d'accéder à des groupes? Très perturbant. Je suppose que je n'ai jamais utilisé complètement cette API auparavant. Apparaît-il que vous devez effectuer au moins un appel à .find() en premier? Sensationnel. API déroutante Je suppose que c'est possible que j'ai seulement utilisé .matches(), bien que j'aurais juré que c'était juste .matcher (....). Group(). –

0

I Donno Java saveur d'expression régulière Cependant cette expression régulière PCRE devrait fonctionner ^([\d_]+v\d_\d).+ ne sais pas pourquoi vous utilisez ._. au lieu de \d_\d

+0

Parce que je n'ai aucune garantie que ce seront toujours des numéros. –

+0

Ensuite, utilisez^([\ d _] + v ._.). + 'Comme vous le faisiez auparavant. Il devrait fonctionner. Si la version a fonctionné ici. Sinon, essayez '^ ([\ d _] + v [^ _] _ [^ _]). +' –

1

Si vous voulez vérifier si une chaîne commence avec le certain modèle que vous devez utiliser Matcher.lookingAt() meth od:

Pattern pattern = Pattern.compile("([0-9_]+v._.)"); 
Matcher matcher = pattern.matcher("117_117_0009v0_172_5738_5740"); 
if (matcher.lookingAt()) { 
    int groupCount = matcher.groupCount(); 
    for (int i = 0; i <= groupCount; i++) { 
    System.out.println(i + " : " + matcher.group(i)); 
    } 
} 

Javadoc:

boolean java.util.regex.Matcher.lookingAt()

tente de faire correspondre la séquence d'entrée, à partir du début de la région , contre le modèle.Comme la méthode des appariements , cette méthode commence toujours au début de la région, ; Contrairement à cette méthode, il n'est pas nécessaire que corresponde à la totalité de la région . Si la correspondance réussit, alors plus d'informations peuvent être obtenues via les méthodes de début, de fin et de groupe. `` GroupCount() `est simplement un wrapper pour la méthode Pattern du même nom

+0

Merci, c'est aussi utile et plus proche de ce que je voulais faire. La plupart de mes problèmes viennent de ce qu'il n'est pas clair qu'un appel à quelque chose comme lookingAt() matches() ou find() doit précéder la tentative d'accès au groupe (n). Le message d'exception n'est pas très utile pour communiquer ce fait. Ajoutez à cela que groupCount() renvoie toujours un avant que vous ayez réellement appliqué le modèle comme mentionné ci-dessus, ce qui implique que vous devriez pouvoir accéder à ce groupe. –

Questions connexes