2010-10-18 6 views
1

Est-ce que ce regex a un ou deux groupes?

J'essaie d'accéder au bookTitle en utilisant le deuxième groupe, mais obtenir une erreur:

Pattern pattern = Pattern.compile("^\\s*(.*?)\\s+-\\s+'(.*)'\\s*$"); 
Matcher matcher = pattern.matcher("William Faulkner - 'Light In August'"); 
String author = matcher.group(1).trim(); 
String bookTitle = matcher.group(2).trim(); 

Répondre

3

Il y a deux groupes, mais l'erreur est parce que rien ne se fait avec le matcher.
Une exception IllegalStateException est lancée lors de la tentative d'obtention du premier groupe à matcher.group(1). L'une des méthodes matches, lookingAt ou find doit être appelée.
Cela devrait faire:

Pattern pattern = Pattern.compile("^\\s*(.*?)\\s+-\\s+'(.*)'\\s*$"); 
Matcher matcher = pattern.matcher("William Faulkner - 'Light In August'"); 
if (matcher.matches()) { 
    String author = matcher.group(1).trim(); 
    String bookTitle = matcher.group(2).trim(); 
    ... 
} else { 
    // not matched, what now? 
} 
4

Deux groupes - ' n'est pas un caractère spécial dans regexes. Quelle est l'erreur que vous obtenez?

En outre, ils NE SONT PAS base zéro. Depuis le javadoc:

Group zero denotes the entire pattern, so the expression m.group(0) is equivalent to m.group().

+1

Juste testé votre regex sur mon ordinateur et cela fonctionne pour moi –

2

Ajoutez l'un des éléments suivants avant de demander des groupes.

matcher.find(); 
matcher.maches(); 

Comment cela fonctionne:

A matcher is created from a pattern by invoking the pattern's matcher method. Once created, a matcher can be used to perform three different kinds of match operations:

The matches method attempts to match the entire input sequence against the pattern.

The lookingAt method attempts to match the input sequence, starting at the beginning, against the pattern.

The find method scans the input sequence looking for the next subsequence that matches the pattern.

Source: Java Api

Personnellement, je recommande de supprimer plusieurs espaces, puis diviser et couper - simple, alto, testé et œuvres.

Essayez ceci:

String s = "William   Faulkner - 'Light In August'"; 
    String o[] = s.replaceAll("\\s+", " ").split("-"); 
    String author = o[0].trim(); 
    String bookTitle = o[1].trim(); 

Si vous:

System.out.println(author); 
    System.out.println(bookTitle); 

Ensuite la sortie serait:

William Faulkner 
'Light In August' 
1

Le problème est que la classe Matcher semble être paresseux: il reporte en fait l'évaluation jusqu'à ce que la méthode matchs() est appelée. Essayez plutôt

Pattern pattern = Pattern.compile("^\\s*(.*)\\s+-\\s+'(.*)'\\s*$"); 
Matcher matcher = pattern.matcher("William Faulkner - 'Light In August'"); 

if (matcher.matches()) { 
    String author = matcher.group(1).trim(); 
    String bookTitle = matcher.group(2).trim(); 

    System.out.println(author + "/" + bookTitle); 
} 
else { 
    System.out.println("No match!"); 
} 

Vous pouvez également changer les groupes (. +) Pour vous assurer que vous ne serez pas obtenir des livres avec des auteurs/titres vides.

Questions connexes