2010-11-11 6 views
35

J'ai un problème avec le replaceAll pour une chaîne multiligne:Java regex replaceAll multiligne

String regex = "\\s*/\\*.*\\*/"; 
String testWorks = " /** this should be replaced **/ just text"; 
String testIllegal = " /** this should be replaced \n **/ just text"; 

testWorks.replaceAll(regex, "x"); 
testIllegal.replaceAll(regex, "x"); 

Les travaux ci-dessus pour Testworks, mais pas pour testIllegal !? Pourquoi est-ce et comment puis-je surmonter cela? J'ai besoin de remplacer quelque chose comme un commentaire/* ... */qui couvre plusieurs lignes.

+0

Et qu'en est-il de cette chaîne: '" Chaîne s = \ "/ * \";/* commentaire */"' –

+0

Eh bien, le point est que l'expression rationnelle MATHING ne doit correspondre qu'au début de la chaîne. Maintenant, il ressemble à ceci :(? S)^\\ s */\\ *. * \\ */Je ne sais pas si, pour le rendre réticent (? S)^\\ s */\\ *. *? \\ */ – Robert

Répondre

59

Vous devez utiliser le drapeau Pattern.DOTALL dire que le point doit correspondre à des sauts de ligne. par exemple.

Pattern.compile(regex, Pattern.DOTALL).matcher(testIllegal).replaceAll("x") 

ou spécifier l'indicateur dans le motif en utilisant par exemple (?s)

String regex = "(?s)\\s*/\\*.*\\*/"; 
+1

C'est la meilleure solution car elle n'interagit pas avec la chaîne regex elle-même, vous spécifiez juste un drapeau. Je ne le savais pas, merci! – Robert

+1

Si vous avez plusieurs commentaires "multilignes", cette méthode supprimera également le texte entre ces commentaires. Utilisez la méthode publiée par Boris à la place. – lepe

7

Le méta-caractère . correspond à n'importe quel caractère autre que le caractère de retour à la ligne. C'est pourquoi votre regex ne fonctionne pas pour les cas de lignes multiples.

Pour résoudre ce problème remplacer . avec [\d\D] qui correspond tout caractère comprenant saut de ligne.

Code In Action

+1

Echanger dans '[\ d \ D]' pour '.' (ce qui signifie normalement' [\ n] ', au moins dans le mode' Pattern.UNIX_LINES') me semble inapproprié parce que ce n'est pas évident ce qu'il fait, parce que c'est 6 caractères pour 1, et parce qu'il y a d'autres façons de le faire. – tchrist

8

Ajouter Pattern.DOTALL à la compilation ou (?s) au motif.