Atelier de motifs · Gratuit

Testeur et débogueur de regex

Écrivez un motif, collez le texte sur lequel vous travaillez vraiment et regardez chaque correspondance s'allumer pendant la saisie, avec les groupes de capture, les groupes nommés, les positions, un aperçu du remplacement et des erreurs de syntaxe expliquées en langage clair plutôt que dans les termes de l'environnement d'exécution.

Le RegExp de votre navigateur · Rien n'est importé
Signaler un problème

Espace de travail des expressions régulières

3 correspondances, 3 groupes de capture. Première correspondance à l'index 9.

Motif

Écrivez-le sans les barres obliques

Ou collez un littéral complet comme /\d+/gi et les drapeaux suivent. Tout ce qui se trouve en dessous est recalculé à chaque frappe.

g

Compilation réussie. 3 groupes de capture (year, month, day) · motif de 70 caractères.

Drapeaux
Correspondances dans le texte de test
3

/\b(?<year>\d{4})-(?<month>0[1-9]|1[0-2])-(?<day>0[1-9]|[12]\d|3[01])\b/g sur 114 caractères.

Correspondances
3
Groupes de capture
3
Groupes nommés
3
Largeur nulle
0
Texte couvert
26.3%
Durée d'exécution
–
Texte de test

Le texte sur lequel le motif s'exécute

Les correspondances se colorent pendant la saisie. Les correspondances adjacentes alternent de teinte et chacune porte un trait sur son bord gauche, pour que deux résultats qui se touchent ne se lisent jamais comme un seul.

114 / 100,000 caractères · 4 lignes

Résultats

Toutes les correspondances, avec leurs positions et leurs groupes de capture.

Correspondance n° 1 · groupes de capture
de l'index 9 à 19
  • $1year2026
  • $2month07
  • $3day27

Activez le drapeau d pour voir où se trouve chaque groupe, pas seulement ce qu'il contient.

Bibliothèque de préréglages

Des motifs honnêtes sur ce qu'ils détectent

Chacun charge son motif, ses drapeaux, un remplacement et un texte d'exemple contenant les cas qu'il rejette délibérément.

Contrôles de forme

Des motifs ancrés qui vérifient si une ligne entière a la bonne forme.

Trouver des éléments dans un texte

Des motifs non ancrés qui extraient des éléments d'un texte courant ou de journaux.

Réécriture

Des motifs dont l'intérêt est la substitution plutôt que la recherche.

Aide-mémoire

Chaque token, ce qu'il signifie et le plus petit exemple qui le montre

La syntaxe JavaScript en particulier : les notes signalent les endroits où elle se sépare de PCRE et de Python.

Classes de caractères

Une position dans le texte et l'ensemble des caractères autorisés à l'occuper.

.
N'importe quel caractère sauf un saut de ligne, à moins que le drapeau s soit activé./a.c/ correspond à « abc », « a-c », pas à « a\nc »
[abc]
N'importe lequel des caractères listés./[aeiou]/ sur « rhythm » ne trouve rien
[^abc]
N'importe quel caractère non listé. L'accent circonflexe doit venir en premier./[^0-9]/ sur « a1 » correspond à « a »
[a-z]
Une plage, dans l'ordre des points de code./[a-f0-9]/ est un chiffre hexadécimal
\d \D
Un chiffre ASCII, et tout ce qui n'en est pas un. \d vaut exactement [0-9] ; il n'inclut pas les chiffres indo-arabes ni les chiffres pleine chasse./\d{4}/ sur « year 2026 » correspond à « 2026 »
\w \W
Un caractère de mot [A-Za-z0-9_], et son complément. Les lettres accentuées ne sont pas des caractères de mot./\w+/ sur « café » correspond à « caf »
\s \S
Un blanc (espace, tabulation, saut de ligne, saut de page, NBSP et les séparateurs d'espace Unicode), et son complément./\s+/ fusionne les suites de blancs
\p{…}
Une propriété Unicode. Nécessite le drapeau u ; sans lui, \p signifie un « p » littéral./\p{Lu}/u correspond à une lettre majuscule de n'importe quelle écriture

Quantificateurs

Combien de fois l'élément précédent peut se répéter. Gourmands par défaut ; ajoutez ? pour les rendre paresseux.

*
Zéro ou plus. Réussit toujours, c'est pourquoi /a*/g correspond partout./ab*c/ correspond à « ac » et à « abbbc »
+
Un ou plus./\d+/ sur « abc123 » correspond à « 123 »
?
Zéro ou un : l'atome est facultatif./colou?r/ correspond aux deux orthographes
{3}
Exactement trois fois./\d{3}/ correspond à « 555 »
{2,}
Deux fois ou plus, sans limite supérieure./o{2,}/ sur « ooooh » correspond à « oooo »
{2,4}
Entre deux et quatre fois./a{2,4}/ sur « aaaaa » correspond à « aaaa »
*? +? ?? {n,m}?
Les formes paresseuses : prendre le moins possible et ne grandir que si le reste du motif échoue./<.+?>/ sur « <a><b> » correspond à « <a> », pas à « <a><b> »

Ancres et limites

Assertions de largeur nulle. Elles ne consomment rien et ne s'intéressent qu'à la position.

^
Début du texte, ou début de n'importe quelle ligne avec le drapeau m./^ERROR/m trouve chaque ligne qui commence par ERROR
$
Fin du texte, ou fin de n'importe quelle ligne avec le drapeau m./;$/m trouve les lignes qui se terminent par un point-virgule
\b
Une limite de mot : entre un \w et un non-\w. Définie sur les caractères de mot ASCII, elle tombe donc au milieu du mot dans « naïve »./\bcat\b/ ne correspond pas à « category »
\B
Pas une limite de mot./\Bcat/ correspond au « cat » à l'intérieur de « bobcat »

Groupes, alternance, références

La capture est ce qui transforme un test en données extraites, et ce qui coûte de la mémoire quand vous n'en aviez pas besoin.

(…)
Groupe de capture, numéroté de gauche à droite selon la parenthèse ouvrante./(\d+)-(\d+)/ donne deux groupes
(?:…)
Groupe non capturant. Même regroupement, aucun emplacement dans le résultat./(?:ab)+/ répète « ab » et ne capture rien
(?<name>…)
Groupe de capture nommé, ES2018. Disponible via match.groups.name./(?<year>\d{4})/ puis match.groups.year
|
Alternance, essayée de gauche à droite. La première branche qui permet à tout le motif de réussir l'emporte./cat|category/ sur « category » correspond à « cat »
\1
Référence arrière : le texte exact que le groupe 1 a déjà trouvé./(\w+) \1/ trouve un mot répété
\k<name>
Référence arrière vers un groupe nommé./(?<q>['"]).*?\k<q>/ correspond à des guillemets équilibrés

Lookaround

Des assertions qui inspectent le texte autour de la position courante sans le consommer.

(?=…)
Lookahead : ce qui suit doit correspondre./\d+(?= kg)/ sur « 80 kg » correspond à « 80 »
(?!…)
Lookahead négatif : ce qui suit ne doit pas correspondre./\bfoo(?!bar)/ ignore « foobar »
(?<=…)
Lookbehind : ce qui précède doit correspondre. ES2018 et, contrairement à la plupart des moteurs, JavaScript l'autorise à avoir une longueur variable./(?<=£)\d+/ sur « £40 » correspond à « 40 »
(?<!…)
Lookbehind négatif : ce qui précède ne doit pas correspondre./(?<!un)happy/ ignore « unhappy »

Drapeaux

Définis pour la regex dans son ensemble. JavaScript n'a pas de modificateur en ligne (?i) : le drapeau s'applique partout ou nulle part.

g
Global : toutes les correspondances, et lastIndex est conservé entre les appels à exec./a/g avec matchAll
i
Insensible à la casse./hello/i correspond à « HELLO »
m
Multiligne : ^ et $ correspondent aux sauts de ligne. N'affecte pas le point./^\s*$/m trouve les lignes vides
s
Dot-all : . correspond aussi aux sauts de ligne./<p>.*<\/p>/s s'étend sur plusieurs lignes
u
Mode Unicode : points de code, \p{…}, \u{…} et échappements stricts./^.$/u correspond à un seul emoji
y
Adhérent : ne correspond qu'à lastIndex, sans avancer.Les tokeniseurs font avancer lastIndex à la main
d
Indices : match.indices contient [start, end] pour chaque groupe.match.indices[1] localise le groupe 1

Échappements et littéraux

Douze caractères sont spéciaux. Pour en rechercher un littéralement, placez une barre oblique inverse devant.

\. \* \+ \?
Les métacaractères, pris littéralement. L'ensemble complet est . * + ? ^ $ { } ( ) | [ ] \/\d+\.\d+/ correspond à « 3.14 »
\\
Une barre oblique inverse littérale. Dans un littéral de chaîne, elle se double encore pour donner \\\\.new RegExp("\\\\d") équivaut à /\\d/
\n \r \t
Saut de ligne, retour chariot, tabulation./\r?\n/ découpe sur l'une ou l'autre fin de ligne
\xFF
Un caractère par son code hexadécimal à deux chiffres./\x41/ correspond à « A »
\u00e9
Un caractère par son code hexadécimal à quatre chiffres./\u00e9/ correspond à « é »
\u{1F600}
Un point de code au-delà de U+FFFF. Nécessite le drapeau u./\u{1F600}/u correspond à un emoji
\0
Le caractère NUL. Ce n'est pas un échappement octal : ceux-ci sont interdits avec u./\0/ correspond à U+0000

C'est le moteur de votre navigateur

Le motif va directement au constructeur RegExp de l'environnement d'exécution, donc ce que vous voyez est ce que feront Node et le navigateur. Le module re de Python, PCRE, RE2 de Go et grep diffèrent tous : parfois par la syntaxe, parfois par le sens d'une syntaxe identique.

\d vaut [0-9] ici, et pas partout

JavaScript maintient \d, \w et \b sur l'ASCII quel que soit le drapeau u. Python et .NET élargissent par défaut \d à tous les chiffres décimaux Unicode, donc ٢٠٢٦ passe là-bas et échoue ici. Demandez \p{Nd} quand vous voulez le sens large.

L'imbrication est hors de portée

Aucune expression régulière ne peut reconnaître des parenthèses équilibrées, ce qui exclut HTML, JSON et le code source, quelle que soit la longueur du motif. Le préréglage HTML de cette page est volontairement présenté comme un survol, pas comme un analyseur.

Tout ce qui se trouve sur cette page s'exécute dans votre navigateur, avec la propre implémentation de RegExp de votre navigateur : aucun motif, aucun texte de test et aucun résultat n'est jamais envoyé nulle part. Les garde-fous sont énoncés plutôt que sous-entendus : jusqu'à 100,000 caractères de texte de test, 5,000 correspondances et 250 ms de temps réel par exécution, après quoi l'exécution s'arrête et le signale. Une correspondance de longueur nulle fait toujours avancer le curseur d'un point de code entier, donc un motif comme /a*/g se termine au lieu de boucler.

Comment ça marche

Un motif, un texte, et tout ce que le moteur sait de ce couple.

Une expression régulière est un minuscule programme, et elle est difficile à déboguer parce qu'elle s'exécute de façon invisible : vous voyez la réponse, jamais le raisonnement. Cette page rend le raisonnement visible. Votre motif est compilé par le constructeur RegExp du navigateur lui-même, exécuté sur votre texte avec une limite de longueur, de nombre de correspondances et de temps réel, puis présenté correspondance par correspondance : où chacune commence et se termine, ce que contient chaque groupe de capture, quels groupes n'ont pas participé du tout et ce que produirait une substitution. Comme il s'agit du moteur de l'environnement d'exécution et non d'une réimplémentation, les résultats sont ceux qu'obtiendra votre JavaScript. Honnêtement, ce ne sont pas ceux qu'obtiendront Python, PCRE, RE2 de Go ou grep.

  1. 01

    Écrivez le motif et choisissez les drapeaux

    Tapez le motif sans les barres obliques qui l'entourent, ou collez un littéral complet comme /\d+/gi et les drapeaux suivent. Chacun des sept drapeaux est un interrupteur légendé plutôt qu'une lettre à retenir, et une erreur de syntaxe est expliquée en une phrase au lieu de reprendre la formulation de l'environnement d'exécution.

  2. 02

    Collez le texte sur lequel vous travaillez vraiment

    Une vraie entrée, pas un exemple artificiel : un extrait de journal, une colonne CSV, une page de prose. Les correspondances sont surlignées pendant la saisie, avec des teintes alternées pour que deux correspondances qui se touchent restent deux correspondances, et une correspondance de largeur nulle est dessinée comme un repère au lieu de disparaître.

  3. 03

    Lisez les groupes, puis essayez la substitution

    Chaque correspondance affiche ses positions et chaque groupe numéroté et nommé, y compris ceux qui n'ont pas participé. Passez à Remplacer pour prévisualiser une substitution avec $1, $<name>, $& et compagnie développés, ou à Découper pour voir ce que String.split fait du même motif.

Conçu pour déboguer, pas pour faire des démonstrations

Ce que les autres testeurs arrondissent : correspondances vides, groupes absents et motifs qui résistent.

Une recherche qui ne peut pas bloquer l'onglet

Une correspondance de longueur nulle fait avancer le curseur d'un point de code entier, donc /a*/g se termine au lieu de boucler indéfiniment. Un budget de temps réel arrête une exécution qui a commencé à s'enliser et indique que le motif fait un backtracking excessif, au lieu de figer la page derrière un indicateur de chargement qui ne s'arrête jamais.

Les groupes qui n'ont pas participé restent affichés

Avec /(a)|(b)/ sur « b », le groupe 1 vaut undefined et le groupe 2 contient la correspondance. Les testeurs qui suppriment l'emplacement vide renumérotent silencieusement tout ce qui suit. Ici, l'emplacement reste, marqué comme n'ayant pas participé, et c'est exactement cette distinction qui casse le code en aval.

Des positions pour chaque groupe, pas seulement pour la correspondance

Activez le drapeau d et chaque capture indique ses propres indices de début et de fin, lus dans match.indices. Sans lui, vous obtenez la position de la correspondance entière et devez rechercher à nouveau le texte du groupe, ce qui échoue dès que le même texte apparaît deux fois.

Un aperçu du remplacement qui développe les cas délicats

$1, $<name>, $&, $` et $' et $$ sont tous développés ici plutôt que décrits, y compris la règle selon laquelle $12 désigne le groupe 12 s'il existe et le groupe 1 suivi d'un « 2 » sinon. Le résultat est vérifié par rapport à ce que produit String.replace.

Des erreurs de syntaxe traduites en quelque chose d'exploitable

« Invalid regular expression: /(/: Unterminated group » devient « Une ( a été ouverte mais jamais fermée », avec une note précisant qu'une parenthèse littérale doit être échappée. Une quinzaine de familles d'erreurs sont reconnues, quelle que soit la formulation utilisée par V8, JavaScriptCore ou SpiderMonkey.

Dix préréglages qui disent ce qu'ils détectent vraiment

Le motif d'e-mail est présenté comme la forme pragmatique qui repère les fautes de frappe, pas comme une validation RFC 5322. Celui d'IPv4 limite chaque octet à 255 et reconnaît qu'il trouvera quand même une adresse à l'intérieur d'une chaîne de version. Chaque préréglage est livré avec un texte d'exemple contenant les cas qu'il rejette.

Questions sur les regex

Gourmand contre paresseux, backtracking catastrophique, et là où JavaScript se sépare de PCRE.

Quelle variante de regex cet outil teste-t-il ?+

Celle qui tourne déjà dans votre navigateur. Aucun moteur n'est intégré à cette page : votre motif est transmis au constructeur RegExp de l'environnement d'exécution JavaScript, et les correspondances que vous voyez sont celles qu'obtiendra votre code. Les résultats sont donc exacts pour JavaScript, TypeScript, Node, Deno et Bun. Pour tout le reste, ils ne sont qu'approximatifs. Le module re de Python, PCRE en PHP et Perl, RE2 de Go, la crate regex de Rust, .NET, Java, grep, sed et ripgrep diffèrent tous, parfois par la syntaxe et parfois par le sens d'une même syntaxe. Si le motif est destiné à un autre langage, testez-le dans ce langage avant de le livrer.

Quelle est la différence entre les quantificateurs gourmands et paresseux ?+

Un quantificateur gourmand prend tout ce qu'il peut, puis rend les caractères un par un jusqu'à ce que le reste du motif convienne. Un quantificateur paresseux (qui s'écrit en ajoutant un point d'interrogation : *? +? ?? {n,m}?) prend le moins possible et ne grandit que lorsqu'il y est forcé. La démonstration classique est /<.+>/ sur « <a><b> » : le .+ gourmand avale tout jusqu'à la fin, revient en arrière jusqu'au dernier « > » et renvoie « <a><b> » comme une seule correspondance. Remplacez-le par /<.+?>/ et vous obtenez « <a> », puis « <b> ». Aucun n'est plus correct que l'autre ; ils répondent à des questions différentes. La règle pratique : le gourmand est le bon choix par défaut quand le délimiteur est unique, et le paresseux quand il se répète.

Qu'est-ce que le backtracking catastrophique ?+

C'est ce qui se produit quand un motif peut découper le même texte de très nombreuses façons et que la correspondance finit par échouer. JavaScript cherche les correspondances par backtracking : en cas d'échec, il réessaie donc toutes les combinaisons restantes avant d'abandonner. Le déclencheur classique est une répétition dans une répétition, comme /(a+)+$/ sur une longue suite de « a » suivie d'un seul « b ». Il existe un nombre exponentiel de façons de répartir 30 « a » en groupes d'un ou plusieurs, et le moteur les essaie toutes avant de conclure que le « $ » ne peut pas correspondre. Trente caractères prennent quelques millisecondes ; quarante prennent environ mille fois plus. Les solutions : empêcher les répétitions intérieure et extérieure de correspondre au même texte, remplacer un groupe quantifié par une classe de caractères, ou ancrer le motif pour que l'échec soit détecté tôt. Cette page analyse votre motif à la recherche de ces formes et les nomme avant de l'exécuter.

Pourquoi le lookbehind est-il arrivé si tard en JavaScript ?+

Le lookahead fait partie du langage depuis le début, mais le lookbehind n'est arrivé qu'avec ES2018 (plus de vingt ans plus tard), et jusqu'à ce que Safari le prenne en charge en 2023, un motif qui l'utilisait déclenchait une erreur de syntaxe sur un navigateur que beaucoup de sites devaient encore prendre en charge. Ce retard s'explique en partie par le ralentissement général de l'évolution du langage entre l'abandon d'ES4 et ES6, et en partie par le fait que le lookbehind est réellement plus difficile à implémenter : le moteur doit chercher à reculons depuis la position courante. L'implémentation de JavaScript s'est finalement révélée meilleure que la plupart, car contrairement à PCRE, au module re de Python et à Java, elle autorise un lookbehind de longueur variable. /(?<=\$\d+ )item/ est valide ici et rejeté d'emblée par ces moteurs. Si l'un de vos motifs doit fonctionner dans un environnement ancien, la solution traditionnelle consiste à capturer le contexte précédent dans un groupe et à l'ignorer ensuite.

Quelle est la différence entre les drapeaux u et v ?+

Le drapeau u, introduit par ES2015, fait passer le motif en mode Unicode : les caractères astraux comme les emoji comptent pour une unité au lieu de deux moitiés UTF-16, \u{1F600} devient valide, les échappements de propriété \p{…} sont débloqués, et les échappements sans signification deviennent des erreurs de syntaxe au lieu d'être ignorés en silence. Le drapeau v, introduit par ES2024, est un sur-ensemble qui ajoute une notation ensembliste dans les classes de caractères (différence avec --, intersection avec && et propriétés de chaînes de plusieurs caractères), ce qui permet d'écrire [\p{Letter}--[a-z]] pour dire « n'importe quelle lettre sauf une minuscule ASCII ». Les deux drapeaux s'excluent mutuellement : une regex est en mode u ou en mode v, jamais les deux. Cette page propose u et pas v, car une paire de boutons qui s'annulent silencieusement est une moins bonne interface qu'une interface honnête sur sa portée.

Pourquoi ma regex globale saute-t-elle une correspondance sur deux ?+

Parce qu'une regex portant le drapeau g ou y a un état. Elle stocke une propriété lastIndex, et exec comme test partent de là et la mettent à jour en cas de succès. Stockez-en une dans une constante de niveau module, appelez test deux fois sur la même chaîne, et le second appel commence à mi-chemin et renvoie false. Le même bug survient quand une regex globale est réutilisée d'un élément à l'autre dans une boucle. Il y a trois façons d'en sortir : créer la regex à neuf là où elle est utilisée, remettre lastIndex à 0 avant chaque appel, ou utiliser matchAll et String.match, qui ne laissent pas traîner le curseur là où vous pourriez trébucher dessus. Cette page évite complètement le problème en compilant une copie de travail privée à chaque exécution, si bien que la regex que vous regardez n'est jamais celle qui est modifiée.

Que peut faire PCRE que les regex JavaScript ne peuvent pas faire ?+

Plusieurs choses, et savoir lesquelles évite bien des débogages déroutants quand vous copiez un motif d'un moteur à l'autre. Il n'y a pas de groupes atomiques : le (?>…) de PCRE s'engage sur une correspondance et refuse d'y revenir par backtracking, ce qui est le correctif manuel classique du backtracking catastrophique, et le seul substitut en JavaScript est un lookahead qui enveloppe une capture. Il n'y a pas de quantificateurs possessifs (a*+), pour la même raison. Il n'y a pas de récursion (?R) ni d'appels de sous-routines, donc les parenthèses équilibrées sont hors de portée. Il n'y a pas de modificateurs en ligne : (?i) au milieu d'un motif est une erreur de syntaxe, car un drapeau JavaScript s'applique à toute la regex ou pas du tout. Il n'y a pas de conditionnelles, pas d'ancres \A \z \Z, pas de classes POSIX comme [[:alpha:]], et pas de mode commentaire. Ce que JavaScript possède et que beaucoup de moteurs n'ont pas, c'est le lookbehind de longueur variable.

\d signifie-t-il la même chose partout ?+

Non, et cette différence est une vraie source de failles de sécurité. En JavaScript, \d vaut exactement [0-9], toujours, avec ou sans le drapeau u. En .NET et en Python 3, \d correspond par défaut à tout caractère doté de la propriété Unicode de chiffre décimal, ce qui inclut les chiffres indo-arabes ٠١٢, les chiffres devanagari et les chiffres pleine chasse 012. Un validateur écrit en Python qui accepte ٢٠٢٦ et un validateur JavaScript qui le rejette ne seront pas d'accord sur la même entrée, et c'est précisément le genre d'incohérence qui est exploité. La même prudence s'applique à \w, qui vaut ici [A-Za-z0-9_] et ne considère donc pas « é » comme un caractère de mot, et à \b, qui est défini à partir de \w et tombe donc au milieu de « naïve ». Si vous voulez une sémantique Unicode en JavaScript, vous devez la demander explicitement : \p{Nd} avec le drapeau u pour les chiffres, \p{L} pour les lettres.

Quand faut-il arrêter d'utiliser une expression régulière ?+

Quand ce que vous recherchez peut s'imbriquer. Les expressions régulières au sens formel ne savent pas compter, et même si les références arrière poussent le moteur de JavaScript au-delà d'un langage strictement régulier, il ne peut toujours pas reconnaître une structure équilibrée. Cela exclut HTML, XML, JSON, le code source et tout langage à parenthèses, non pas parce que le motif est difficile à écrire, mais parce qu'aucun motif n'existe. Utilisez DOMParser, JSON.parse ou un vrai analyseur. Trois signaux plus discrets vont dans le même sens : le motif dépasse une ou deux lignes et personne ne peut le lire, il faut un commentaire pour expliquer chaque clause, ou il accumule les cas particuliers pour des entrées qu'il était censé déjà gérer. Une expression régulière est à son meilleur pour trouver et valider des fragments plats et bien formés (une date, une couleur hexadécimale, un préfixe de journal), et à son pire quand elle se fait passer pour une grammaire.

Que signifient $1, $&, $` et $' dans un remplacement ?+

Ce sont les motifs de substitution que String.replace comprend dans la chaîne de remplacement. De $1 à $99, ils insèrent le texte du groupe de capture portant ce numéro, et $<name> fait de même pour un groupe nommé. $& insère la correspondance entière. $` insère tout ce qui précède la correspondance et $' tout ce qui la suit ; les deux sont étonnamment utiles pour encadrer du texte et étonnamment faciles à déclencher par accident, car une barre oblique inverse ne les échappe pas. $$ insère un seul signe dollar littéral. Deux règles piègent souvent : une référence à un groupe qui n'existe pas est laissée telle quelle dans la sortie au lieu de lever une erreur, et $12 désigne le groupe 12 si le motif compte douze groupes, et le groupe 1 suivi du caractère « 2 » sinon. Cette page les développe tous dans l'aperçu et signale toute référence qu'elle n'a pas pu résoudre.

D'autres outils ciblés, prêts quand vous l'êtes.

Découvrez une collection grandissante pour les calculs, les documents, la rédaction et le travail de tous les jours.

Voir tous les outils