2017-10-18 3 views
1

Je suis en train de diviser des lignes d'un document, en créant un Pattern en Java. L'exemple Pattern par défaut dans WordCount est semblable à ceci: "\\s*\\b\\s*". Le problème avec ce modèle, cependant, c'est qu'il divise tout en un seul mot, alors que je veux garder des choses comme (je suis, vous êtes, c'est) ensemble. Jusqu'à présent, ce que j'ai essayé est [a-zA-Z]+'{0,1}[a-zA-Z]*,Regex pour attraper tous les mots et le «je suis vous êtes etc» en Java

le problème est que lorsque j'ai une chaîne de test, par exemple:

Pattern BOUNDARY = "[a-zA-Z]+'{0,1}[a-zA-Z]*" 
String test = "Hello i'm @£[email protected] @@can !!be. 

et exécuter

for(String word : BOUNDARY.split(test){ 
    println(word)} 

-je obtenir aucun résultat. Idéalement, je veux obtenir

Hello 
i'm 
you 
can 
be 

Toutes les idées sont les bienvenues. Dans le regex101.com l'expression rationnelle que j'ai mise en place fonctionne comme un charme, donc je devine que j'ai mal compris quelque chose dans la partie Java.

+0

Il s'agit d'une expression rationnelle * correspondant *, utilisez 'Matcher.find()' pour obtenir toutes les occurrences qui ne se chevauchent pas. –

Répondre

1

Votre motif initial était divisé à une limite de mot entourée d'un motif d'espaces blancs 0+. Le deuxième modèle est correspondant sous-chaînes.

utiliser comme ceci:

String BOUNDARY_STR = "[a-zA-Z]+(?:'[a-zA-Z]+)?"; 
String test = "Hello i'm @£[email protected] @@can !!be."; 
Matcher matcher = Pattern.compile(BOUNDARY_STR).matcher(test); 
List<String> results = new ArrayList<>(); 
while (matcher.find()){ 
    results.add(matcher.group(0)); 
} 
System.out.println(results); // => [Hello, i'm, you, can, be] 

Voir la Java demo

Remarque je [a-zA-Z]+(?:'[a-zA-Z]+)? qui correspond

  • [a-zA-Z]+ - 1 ou plusieurs lettres ASCII
  • (?:'[a-zA-Z]+)? - une sous-chaîne en option de
    • ' - une apostrophe
    • [a-zA-Z]+ - 1 ou plusieurs lettres ASCII

Vous pouvez également envelopper le motif avec des limites de mots à seulement les mots qui sont enfermés avec les caractères non-mot, "\\b[a-zA-Z]+(?:'[a-zA-Z]+)?\\b" .

Pour rechercher toutes les lettres Unicode, utilisez "\\p{L}+(?:'\\p{L}+)?".

+0

Merci beaucoup, je pensais avoir quelque chose de mal dans mon esprit, je ne savais pas comment le réparer. Pourquoi utilisez-vous cette syntaxe pour la sous-chaîne optionnelle? Est-ce plus optimal que ma version? – CnewbieWannabePro

+0

Si vous utilisez 'a + '? A *', vous devrez faire correspondre 'a''. En outre, s'il n'y a pas de '' 'dans la chaîne, le modèle fonctionnera comme' a + a * 'ce qui n'a pas beaucoup de sens. Mon exemple implique moins de retour en arrière. Si vous avez besoin de "a", remplacez simplement le dernier '+ 'par' * '. –