2010-07-23 3 views
1

Je n'arrive pas à obtenir des expressions régulières avec des caractères de début/de fin correspondant à Java (1.6.20).

A partir de ce code:

System.out.println("$40".matches("\\b\\Q$40\\E\\b")); 
System.out.println("$40".matches(".*\\Q$40\\E.*")); 
System.out.println("$40".matches("\\Q$40\\E")); 
System.out.println(" ------ "); 
System.out.println("40$".matches("\\b\\Q40$\\E\\b")); 
System.out.println("40$".matches(".*\\Q40$\\E.*")); 
System.out.println("40$".matches("\\Q40$\\E")); 
System.out.println(" ------ "); 
System.out.println("4$0".matches("\\b\\Q4$0\\E\\b")); 
System.out.println("40".matches("\\b\\Q40\\E\\b")); 

-je obtenir ces résultats:

false 
true 
true 
------ 
false 
true 
true 
------ 
true 
true 

Le premier faux dans les deux premiers blocs semblent être le problème. C'est-à-dire que le signe avant/arrière $ (signe dollar) n'est pas repris correctement dans le contexte du marqueur \ b (limite de mot). Les vrais résultats dans les blocs montrent que ce n'est pas le signe dollar lui-même, puisque remplacer le b avec un. * Ou supprimer tous ensemble donne le résultat désiré. Les deux derniers résultats "true" montrent que le problème ne se trouve pas dans une citation interne de $ ni avec correspondance sur les limites de mot (\ b) dans l'expression quotée "\ Q ... \ E".

Est-ce un bug de Java ou manque-t-il quelque chose?

+0

Ne pas supprimer; Il suffit de marquer Tomalak la bonne réponse, ou de clarifier si vous avez découvert quelque chose. Aide les personnes qui ont le même problème et qui recherchent en ligne pour cela. – Will

+0

Merci pour le conseil, Will - accepté ci-dessous. –

Répondre

2

Cela est dû au fait que \b correspond aux limites des mots. Et la position immédiatement avant ou après un caractère $ ne compte pas nécessairement comme une limite de mot.

Une limite de mot est la position entre \w et \W, et $ ne fait pas partie de \w. Sur l'exemple de la chaîne « $ bla », les limites de mots sont:

" b l a $ " 
^----------- here 

" b l a $ " 
     ^----- here 

" b l a $ " 
     ^--- but not here 
1

Tomalak clouée - il est sur la correspondance de limite de mot. Je l'avais compris et supprimé la question, mais le conseil de Will de rester ouvert aux autres est solide. Le \b était, en fait, le coupable. Une conclusion pourrait être que, pour tout autre chose que les utilisations les plus rudimentaires (c'est-à-dire ASCII), les expressions pratiques intégrées de Java sont effectivement inutiles. Par exemple. \w correspond uniquement des caractères ASCII, \b est sur cette base, etc.

FWIW, mon RegExp a fini par être:

(?:^|[\p{P}\p{Z}])(\QThe $earch Term\E)(?:[\p{P}\p{Z}]|$) 

The $earch Term est le texte que je suis en train de faire correspondre. Les codes \p{} sont les catégories Unicode. Fondamentalement, je me moque de tout caractère dans les catégories de caractère Unicode (P) ou Séparateur (Z). De plus, le début et la fin de l'entrée sont respectées (avec ^ et $) et les bornes sont étiquetés en tant que groupes non-capture (les (?:...) des bits), tandis que le terme de recherche actuelle est cité avec \Q et \E & placé dans un appariement groupe.

+0

'\ b' fonctionne bien; vous essayiez juste de l'utiliser au mauvais endroit. Et '\ b' * est * Unicode savvy; il utilise 'Character.isLetterOrDigit()', pas '\ w', pour décider quel est un caractère de mot et ce qui ne l'est pas. –

Questions connexes