11557 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous
Je sèche sur l’écriture d’une expression régulière pour obtenir le résultat suivant.
Soit une chaîne de caractères de la forme
(!aaaaa):bbbb(:cccc(:dddd…))
Les parenthèses indiquent des parties optionnelles
Les chaînes aaaa, bbbb, etc. sont de la forme
[a-z][-a-z0-9]*
Je voudrais récupérer
['aaaa', 'bbbb', 'cccc’, 'dddd’, …]

avec la première valeur = '' si le premier champ n’existe pas.
Actuellement je récupère uniquement le premier et le dernier champ Smiley decu
Merci de votre aide
Modifié par PapyJP (05 Sep 2025 - 10:13)
Administrateur
Bonjour,

pas réussi en 5 minutes mais une IA a fait mieux mais pas parfait en 10s Smiley biggrin .
Vu ton résultat actuel, je suppose que c'est en JS et pas en PHP, ou bien ?

Pour du JS, voilà ce que ChatGPT en dit :

/*
In JS, I need to capture each group of 4 chars ; here are 4 examples. How?
```
:bbbb:cccc:dddd
!aaaa:bbbb:cccc:dddd
!aaaa:bbbb:cccc:dddd:eeee:ffff
:bbbb:cccc:dddd:eeee:ffff
```
*/
const input = [
  ":bbbb:cccc:dddd",
  "!aaaa:bbbb:cccc:dddd",
  "!aaaa:bbbb:cccc:dddd:eeee:ffff",
  ":bbbb:cccc:dddd:eeee:ffff"
];

input.forEach(str => {
  const regex = /(?:!|:)([a-z0-9]{4})/g;
  let match;
  const results = [];

  while ((match = regex.exec(str)) !== null) {
    results.push(match[1]); // Capturing group 1
  }

  console.log(results); // Outputs the captured 4-character groups
});

Et c'est correct avec ces exemples-là MAIS ça capture aussi des chaînes ne commençant pas par ! ou : comme "aaaa:nope:cccc:dddd:eeee:ffff" Smiley confus . Avec une petite modif, j'arrive à récupérer [ "nope", "cccc", "dddd", "eeee", "ffff" ] mais est-ce que c'est voulu ou non ?
Si tu as des contre-exemples, ça peut nous aider.
Modérateur
Salut,

J'avoue ne pas avoir bien compris. Donne-nous des exemples probants et ce que tu souhaites capturer.
Le problème de l'AI c'est d'arriver à lui expliquer le problème
Voici la RegEx que j'ai écrite

/^(![a-z][-a-z0-9]+)?(:[a-z][-a-z0-9]+)*$/gi

Sur un exemple comme

let text = '!toto120:abc-DEF:tqp34';
let result = text.match(/^(![a-z][-a-z0-9]+)?(:[a-z][-a-z0-9]+)*$/gi);

Je m'attendais à obtenir

[ '!toto120:abc-DEF:tqp34', 'toto120', 'abc-DEF', 'tqp34']

ce qu j'obtiens c'est

[ '!toto120:abc-DEF:tqp34', 'tqp34']

Modifié par PapyJP (05 Sep 2025 - 17:50)
Salut,

J'ai demandé à ChatGPT :
a écrit :
Regex JavaScript : pour "!toto120:abc-DEF:tqp34" il faudrait que j'obtienne : [ '!toto120:abc-DEF:tqp34', 'toto120', 'abc-DEF', 'tqp34']

Réponse :
^!(\w+) [decu][\w-]+) [decu]\w+)$

J'ai testé sur Regex101, ça fonctionne.

Edit : la regex publiée ici est reformatée par le forum, et donc inopérante, on peut cependant la voir efficiente sur Regex101.
Modifié par Olivier C (06 Sep 2025 - 00:09)
Modérateur
Pourquoi demander à GPT..... ? Smiley eek

Pourquoi utiliser des RegEx ? On peut faire plus simple :

    let strings = [
            ':tata120:abc-DEF:tqp34',
            '!toto120:ghi-JKL:hello123',
        ]
    strings.forEach(str =>{
        let [ one, two, three ] = str.substring(1).split(":").map(e => e.trim())
        console.log(one, two, three)
    })


Si tu souhaites vraiment utiliser une RegEx (c'est moins performant) :

    let pattern = /(?:!|:)([a-z0-9-]+)/gi,
         strings = [
            ':tata120:abc-DEF:tqp34',
            '!toto120:ghi-JKL:hello123',
        ]
    strings.forEach(str =>{
        let matches = [ ...str.matchAll(pattern) ] // générateur dans un Array !
        console.table(matches)
    })


Modifié par Niuxe (05 Sep 2025 - 15:37)
Hmm!
@OlivierC
chatGPT essaie de comprendre le problème à partir de NOMBREUX exemples. Il faudrait plus d'exemples pour que la solution soit (peut-être) acceptable.
Le code généré tient trop compte de l'exemple.
Il y a des espaces dans la RegEx, [\w-] inclut le "_" ce que je ne veux pas, la forme suppose 3 champs et non pas de 1 à ... n champs
C'est quoi "decu" ? pour moi c'est un caractère qui vaut "d", "e", "c" ou "u" je ne vois pas ce que ça vient faire ici
@Niuxe
la décomposition que je fais actuellement ressemble plus ou moins au code proposé, je regarde justement comment faire avec une RegEx pour "simplifier" pour autant que ça simplifie quelque chose...
Mais même si je décide finalement d'en rester à ce que je fais actuellement, j'aimerais bien pour ma gouverne trouver la bonne RegGex pour traiter ce problème.

De plus la solution que tu proposes ne permet pas de valider la conformité de la chaîne de caractères au modèle
1) elle marche si la chaîne de caractères comprend des choses en plus
2) elle ne vérifie pas que lle champ '!xxx" s'il existe est le premier.
Si je dois ajouter du code pour vérifier ces deux points, c'est contreproductif par rapport au code actuel.
Modifié par PapyJP (05 Sep 2025 - 16:03)
À la question
Pourquoi demander à GPT..... ?
je répondrais
parce que c'est la mode du jour... Smiley cligne
Modifié par PapyJP (05 Sep 2025 - 15:54)
Modérateur
PapyJP a écrit :

@Niuxe
la décomposition que je fais actuellement ressemble plus ou moins au code proposé, je regarde justement comment faire avec une RegEx pour "simplifier" pour autant que ça simplifie quelque chose...
Mais même si je décide finalement d'en rester à ce que je fais actuellement, j'aimerais bien pour ma gouverne trouver la bonne RegGex pour traiter ce problème.

De plus la solution que tu proposes ne permet pas de valider la conformité de la chaîne de caractères au modèle
1) elle marche si la chaîne de caractères comprend des choses en plus
2) elle ne vérifie pas que lle champ '!xxx" s'il existe est le premier.
Si je dois ajouter du code pour vérifier ces deux points, c'est contreproductif par rapport au code actuel.


aide forum Alsacreations a écrit :

Conventions d'écriture
....
À question bien posée, réponse vite trouvée
....
veuillez vous relire afin que votre message soit bien compris par tous
....
Merci de bien vouloir prendre le temps de présenter correctement vos messages, surtout si ces messages doivent inciter les autres membres à vous dépanner sur un problème.

aide du forum

Tu n'expliques pas exactement ce que tu souhaites. Tu n'expliques pas le contexte. Ton premier message est abscons. Je dis qu'apriori, tu n'as pas besoin d'une RegEx. Une RegEx c'est moins perfomant. Je ne vois pas pourquoi c'est contre productif. La méthode String.startsWith() devrait aider.
Modifié par Niuxe (05 Sep 2025 - 17:18)
J'aurais dû éviter de fournir des informations sur le pourquoi du comment, qui, ne font qu'embrouiller le lecteur.

Pour le reste
- je ne cherche pas la performance, qui est sans objet dans mon contexte
- je ne cherche pas une autre solution
simplement je voudrais comprendre pourquoi

let text = '!toto120:abc-DEF:tqp34';
let result = text.match(/^(![a-z][-a-z0-9]+)?(:[a-z][-a-z0-9]+)*$/gi);

me donne

[ '!toto120:abc-DEF:tqp34', 'tqp34']

c'est à dire le premier et le dernier item
et non

[ '!toto120:abc-DEF:tqp34', 'toto120', 'abc-DEF', 'tqp34']

et comment il faut modifier ma RegEx pour obtenir le résultat espéré.
PapyJP a écrit :
Il y a des espaces dans la RegEx, [\w-] inclut le "_" ce que je ne veux pas, la forme suppose 3 champs et non pas de 1 à ... n champs
C'est quoi "decu" ? pour moi c'est un caractère qui vaut "d", "e", "c" ou "u" je ne vois pas ce que ça vient faire ici

Je n'avais pas vu, mais à la soumission le forum Alsacreations tente de convertir certains caractères en émoticons à priori... J'avais oublié ce phénomène. Dans le code posté il n'y avait ni espaces, ni "decu".

Je vais tenter de publier la regex en texte brut :

^!(\w+) Smiley decu [\w-]+) Smiley decu \w+)$

Edit: pas mieux Smiley confus , mais sur Regex101 ont a bien la regex que je voulais publier ici.
Modifié par Olivier C (06 Sep 2025 - 00:08)