Accès rapide :
La vidéo
Substitutions par le biais de la classe java.lang.String
Substitutions par le biais de la classe java.util.regex.Pattern
Gestion de la casse (minuscules/majuscules)
Réinjection de valeurs grâce aux expressions régulières
Suppression de valeurs grâce aux expressions régulières
Cette vidéo vous montre comment faire des remplacements (des substitutions) de chaînes de caractères à partir d'expressions régulières.
La classe String
, permettant la manipulation de chaînes de caractères, expose quelques méthodes travaillant avec des expressions régulières.
Parmi ces méthodes, citons String.replaceAll
. Elle ressemble beaucoup à la méthode String.replace
, à la différence que
String.replace
travaille avec des simples chaînes de caractères alors que String.replaceAll
localise les sous-chaînes à
substituer grâce à une expression régulière.
L'exemple ci-dessous remplace toutes les paires de chiffres (quels que soient les chiffres considérés) par la chaîne "xx"
(un peu comme
le brouillage de code d'une carte bleu sur un ticket de transaction).
1 2 3 4 5 6 7 8 9 10 11 |
public class Substitutions { public static void main(String[] args) { // --- Scrambling personal number --- String myPhone = "01 02 03 04 05"; System.out.println( myPhone.replaceAll( "\\d\\d", "xx" ) ); //System.out.println( myPhone.replaceFirst( "\\d\\d", "xx" ) ); } } |
"\"
pose un souci avec l'utilisation des expressions régulières.
Effectivement, ce caractère a du sens dans les deux langages (Java et expressions régulières). Du coup, il est nécessaire dans une chaîne Java de doubler
de caractère afin qu'il soit correctement vu dans l'expression régulière.
Deux autres méthodes similaires existent : replaceFirst
qui ne remplace que la première occurrence de l'expression régulière et
replaceLast
qui ne remplacera que la dernière occurrence.
N'oubliez pas qu'une expression régulière doit être transformée en une machine à nombre d'états fini : nous en avons parlé dans le chapitre précédent.
On parle de compilation d'expression régulière. Si vous utilisez plus d'une fois une expression régulière alors il est vivement conseillé de la compiler
pour garantir des temps d'exécution optimums. Du coup, une question se pose : peut-on aussi faire des substitutions à partir de la classe
Pattern
? Bien entendu, la réponse est ... oui !
Pour rappel, on compile une expression régulière invoquant la méthode Pattern.compile
. Ensuite on récupère un Matcher
permettant
de trouver les correspondances. Voici un exemple qui remplace toutes les ensembles de plusieurs séparateurs (blancs et tabulations) par un seul espace.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import java.util.regex.Pattern; public class Substitutions { public static void main(String[] args) { // --- Replace multiple separators by only one space --- String str = "This is \t a string with\tmultiple \n separators"; Pattern separatorsPattern = Pattern.compile( "\\s+" ); System.out.println( separatorsPattern.matcher( str ).replaceAll( " " ) ); } } |
String
, on retrouve une méthode replaceAll
sur le matcher.
Ce programme affiche, bien entendu, la chaîne This is a string with multiple separators
, sans doubles séparateurs. Le fait de remplacer
chaque occurrence de (\s+
) garanti qu'un tab sera aussi remplacé par un espace (même s'il est seul).
Parfois on souhaite faire des substitutions quand le motif est reconnu en minuscules, mais aussi en majuscules. Dans ce cas, ne doublez
pas l'expression régulière, mais indiquez plutôt que vous souhaitez trouvez les correspondances en étant insensible à la casse. Cela se fait en
rajoutant la valeur Pattern.CASE_INSENSITIVE
en paramètre lors de la compilation de votre expression régulière.
Il est aussi possible de configurer la machine à états en indiquant que la chaîne de caractères sera multi-lignes et que le caractère .
devra correspondre à n'importe quel caractère, y compris retour à la ligne. Pour ce faire, il faudra utiliser la valeur Pattern.DOTALL
.
Voici un exemple qui mixe ces deux configurations.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import java.util.regex.Pattern; public class Substitutions { public static void main(String[] args) { String requestParameter = "Begin\n" + "<Script type='text/javascript'>code</Script>\n" + "Middle\n" + "<script type='text/javascript'>\n" + " window.alert( 'ok' );\n" + "</script>\n" + "End\n"; Pattern removeCodePattern = Pattern.compile("<script[^>]*?>.*?</script>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE); String safeParam = removeCodePattern.matcher( requestParameter ).replaceAll( "" ); System.out.println( safeParam ); } } |
Et voici les résultats produit par cet exemple de code.
$> java Substitutions Begin Middle End $>
Il est possible de réinjecter une donnée sélectionnée par l'expression régulière, quitte à la modifier, dans la chaîne finale.
Pour ce faire, il faudra utiliser une paire de parenthèses pour identifier la donnée à sélectionner dans votre expression régulière.
Puis il faudra utiliser la syntaxe $1
pour réinjecter cette valeur.
Il peut y avoir plusieurs occurrences sélectionnées (via plusieurs paires de parenthèses) et dans ce cas, vous pourrez aussi utiliser $2
, ...
Voici un exemple de réinjection de données. La donnée d'entrée correspond à un code HTML. La donnée réinjectée, une occurrence du mot html
y est mise en gras (tag <b> ... </b>
).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import java.util.regex.Pattern; public class Substitutions { public static void main(String[] args) { // --- Bold some words in an HTML stream --- String message = "This is an HTML content injected in a html tag"; Pattern boldPattern = Pattern.compile( "(html)", Pattern.CASE_INSENSITIVE ); System.out.println( boldPattern.matcher( message ).replaceAll( "<b>$1</b>" ) ); } } |
Et voici le résultat produit par cet exemple.
$> java Substitutions This is an <b>HTML</b> content injected in a <b>html</b> tag $>
En fait, nous avons déjà répondu à ce besoin : en remplaçant les occurrences sélectionnées par l'expression régulière par ""
, on supprime
les valeurs de la chaîne finale.
Améliorations / Corrections
Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.
Emplacement :
Description des améliorations :