5553 sujets

Sémantique web et HTML

Bonjour, à tous,
J’ai constaté que l’expression régulière suivante fonctionne correctement sur https://regex101.com/ :
^\p{Lu}$

Lorsque j’essaie cependant d’utiliser cette même expression dans une balise input HTML, cela ne semble pas fonctionner :
<input
  id="majuscule"
  name="majuscule"
  type="text"
  pattern="^\p{Lu}$"
  title="Majuscule.">

Est-ce que j'ai commis une erreur de syntaxe, ou bien y a-t-il une explication officielle quant à cette incompatibilité qui nous obligerait par conséquent à devoir passer par JavaScript ? Existe-t-il une solution alternative pour utiliser les propriétés Unicode dans les motifs pattern d'un formulaire HTML ?

Je vous remercie d'avance pour votre aide et vos conseils.
Modérateur
Et l'eau,

Je ne pense pas que ce soit pertinent de faire un \p (ça sent pas bon de toutes manières). Il est fort probable que l'attribut pattern d'un élément html ne reconnaisse pas ce raccourci. Quel motif cherches-tu as à capturer ?

edit: ce motif ne fonctionne pas ?

[A-ZÀ-Ö]+

Si tu souhaites récupérer la chaîne de caractères en majuscule, tu n'es pas obligé de demander à l'utilisateur de remplir le champ en majuscule. Dans ton contrôleur, tu passes la donnée en majuscule. Un formulaire, c'est toujours chiant à remplir. Tu risques de perdre ton utilisateur.

Tu peux même forcer la casse lors de la saisie. Ainsi, si l'utilisateur remplit en minuscule, ça renvoie automatiquement en majuscule. C'est valable seulement en JS. Car en CSS, ce n'est que de la peinture

document.querySelector('input').addEventListener('keyup', e => e.target.value = e.target.value.toUpperCase())

Modifié par niuxe (22 Mar 2024 - 20:48)
Bonjour, Niuxe,

Je tenais d’abord à te remercier pour ta contribution à cette discussion. Pour apporter un peu de clarté, l’exemple que j’ai utilisé avec la catégorie Unicode Lu (Lettre Majuscule) visait principalement à simplifier notre échange et à établir une base commune de compréhension.

Il apparait en effet important dans certaines situations d’exiger de l’utilisateur qu’il saisisse des caractères bien précis. Cette précision peut grandement aider à minimiser les erreurs de saisie et améliorer la qualité des données recueillies. Deviner l’intention de l’utilisateur pourrait parfois s’avérer risqué et mener à des interprétations erronées.

La séquence [A-ZÀ-Ö] que tu as mentionnée, bien qu’efficace dans son champ d’application, ne couvre en réalité qu’un nombre limité à 49 caractères. Cela pose un véritable problème lorsqu’on cherche à traiter un spectre plus large de lettres majuscules (pour reprendre mon exemple) présentes dans l’ensemble Unicode. La méthode .toUpperCase() essaie d’autre part de transformer les 1445 lettres minuscules (Ll) en leurs équivalents majuscules, bien que le nombre de lettres majuscules (Lu) est nettement inférieur (1127). Cette différence souligne une complexité inhérente à la gestion des cas de figure variés offerts par Unicode qui pourrait induire des bogues difficiles à déceler.

L’objet de ma question est donc en fait de connaitre les raisons officielles derrière certaines des limitations rencontrées avec l’utilisation des attributs pattern dans les formulaires HTML lors de l’utilisation d’Unicode. Cela pourrait nous offrir des perspectives précieuses sur la façon de naviguer parmi ces contraintes tout en fournissant une expérience utilisateur optimale.

Merci encore pour ton temps et pour ton expertise. J’apprécie grandement l’opportunité d’apprendre et de discuter de ces sujets.
Modifié par Pyanepsion (23 Mar 2024 - 08:34)
Modérateur
Bonjour,

Il faut que la balise <input> soit dans une balise <form> et que le formulaire soit soumis pour que la vérification ait lieu. D'autre part, les ^ et $ en début et fin de regex sont inutiles car la regex s'applique à la totalité de la valeur de l'input dans tous les cas.

Le code suivant fonctionne et vérifie bien si l'entrée est une (et une seule) majuscule ou pas (tel que l'a compris le W3C Smiley biggrin ) une fois qu'on a cliqué sur le bouton "OK".
<form>
<input
  id="majuscule"
  name="majuscule"
  type="text"
  pattern="\p{Lu}"
  title="Majuscule.">
<button>OK</button>
</form>


Amicalement,
Merci Paesimonhi.
Dans le contexte où on a des mots en majuscules séparés par des espaces, cela fonctionne fort bien quand il s'agit d'avoir des mots en lettres capitales séparés par des espaces :
pattern="\p{Lu}+(?: \p{Lu}+)*"

Lorsque j'essaye une autre séquence, où le champ doit commencer par une majuscule ou une lettre en casse de titre, suivi de minuscules, et peut inclure plusieurs mots séparés par des espaces ou des tirets suivant le même modèle, cela fonctionne très bien en JavaScript.
const regex = new RegExp("^(\\p{Lu}|\\p{Lt})\\p{Ll}*(?:[ -](\\p{Lu}|\\p{Lt})\\p{Ll}*)*$", "u");

Mais pas en HTML :
pattern="(\p{Lu}|\p{Lt})\p{Ll}*(?:[ -](\p{Lu}|\p{Lt})\p{Ll}*)*"
Modérateur
Bonjour,

Pas de bol ! Smiley biggrin Smiley biggrin Smiley biggrin

1) Avec l'attribut pattern, le flag de la regex est supposé être "v" et non pas "u". Et avec le flag "v", la regex (\p{Lu}|\p{Lt})\p{Ll}*(?:[ -](\p{Lu}|\p{Lt})\p{Ll}*)* est invalide (que ce soit comme valeur de l'attribut pattern ou en javascript, c'est invalide dans les deux cas). Pour qu'elle soit valide, il faut rajouter un \ devant le - dans [ -]. C'est une des différences entre le flag "v" et le flag "u" qui lui considère [ -] comme valide (ce qui explique pourquoi tu as pu penser que ça marchait en javascript et pas avec l'attribut pattern alors qu'en fait tu ne testais pas tout à fait la même chose). La raison de cette différence entre le flag u et le flag v est que le flag v ajoute des possibilités syntaxiques qui nécessitent que - soit précédé d'un \ quand il doit être considéré comme un caractère normal (literal character en anglais) lorsqu'il est entre des [ ].

2) Je ne vois pas trop ce que tu veux faire avec le ?:

3) J'aurais mis :
pattern="(\p{Lu}|\p{Lt})\p{Ll}*([ \-](\p{Lu}|\p{Lt})\p{Ll}*)*"

Amicalement,
En résumé, je veux capturer le trait d’union, et toi tu me dis de le laisser s’échapper. Smiley biggrin

Bonjour, Parsimonhi,

(Je dois admettre que je suis tombé dans le piège de l’échappement du trait d’union plus d’une fois. Je suis resté avec l’idée que le trait d’union était interprété comme un caractère littéral s’il était placé en début ou en fin de classe de caractères (ou s’il était échappé). Cette confusion m’a déjà causé quelques maux de tête par le passé, et je n’avais visiblement pas encore assez galéré pour m’en souvenir.)

Mon utilisation de « ?: » a pour objectif d’exploiter les groupes non capturants pour améliorer potentiellement les performances lors de l’analyse de textes long et complexes. Je vois cela comme une façon d’optimiser le traitement en évitant la sauvegarde de correspondances intermédiaires non nécessaires. Cela me semble utile aussi pour clarifier l’expression en signalant que certaines données capturées ne sont pas destinées à être réutilisées.

Si tu tapes « AB CD EF GH » dans [code=https://regex101.com/]https://regex101.com/[/code] tu obtiens 14 informations sur la correspondance sans « ?: » et déjà plus que 11 avec.

Qu’en penses-tu ?

Je suis par contre intrigué par la mention de ton drapeau « v ». Pourrais-tu m’en dire plus à ce sujet ? C’est la première fois que j’en entends parler, et cela pourrait ouvrir des perspectives.

Merci d’avance pour tes éclaircissements !
Modifié par Pyanepsion (24 Mar 2024 - 10:05)
Modérateur
Bonjour,

Pyanepsion a écrit :
Si tu tapes « AB CD EF GH » dans [code=https://regex101.com/]https://regex101.com/[/code] tu obtiens 14 informations sur la correspondance sans « ?: » et déjà plus que 11 avec.

Qu’en penses-tu ?
J'en pense qu'il faudrait tester. Et j'en pense aussi que si tu mets un ?: à certaines parenthèses, il faudrait les mettre aux autres aussi, ce qui n'était pas le cas dans ton exemple.

Pyanepsion a écrit :
Je suis par contre intrigué par la mention de ton drapeau « v ». Pourrais-tu m’en dire plus à ce sujet ? C’est la première fois que j’en entends parler, et cela pourrait ouvrir des perspectives.
Ils s'ennuyaient au W3C alors ils ont ajouté le drapeau v. C'est récent (un an ou deux). Je ne l'ai pas utilisé jusqu'à présent. Ça introduit essentiellement de nouvelles manières de définir des classes de caractères (ce qui se trouve entre [ et ] dans une regex)., et en particulier la possibilité de faire des "unions" ou des "différences" au sens mathématique du terme entre deux ensembles de caractères.

Voir https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Character_class#v-mode_character_class

Amicalement,
Le drapeau « v » semble effectivement offrir des possibilités intéressantes, notamment dans la définition avancée des classes de caractères.

<!-- Groupe capturant -->
^(\p{Lu}|\p{Lt})\p{Ll}*([ \-](\p{Lu}|\p{Lt})\p{Ll}*)*$ 

Lorsque des groupes capturants sont utilisés, le moteur de regex enregistre les portions de la chaine qui correspondent à chaque groupe pour une utilisation ultérieure. Ainsi, pour une chaine telle que « Ab Cd Ef Gh », on obtient quatre informations de correspondance : une globale et une pour chaque groupe capturant.

<!-- Groupe non capturant -->
^(?:\p{Lu}|\p{Lt})\p{Ll}*(?:[ \-](?:\p{Lu}|\p{Lt})\p{Ll}*)*$

À l’inverse, l’utilisation de groupes non capturants, réalisé par ?: dans évite la sauvegarde de ces données intermédiaires. Cela se traduit par une unique information de correspondance globale, simplifiant le résultat sans impacter le nombre de pas calculés ni le temps d’exécution, qui demeure de 27 pas en 0,0 s. Cette optimisation reflète une utilisation des ressources plus sobre, ce qui est bon et plus respectueux pour notre planète.

Cette approche distingue les situations où la capture de sous-chaines spécifiques est nécessaire de celles où seul le résultat global est recherché. Un choix judicieux entre groupes capturants et non capturants peut donc concilier efficacité technique et clarté du code.
Modérateur
Bonjour,

Pyanepsion a écrit :
Cela se traduit par une unique information de correspondance globale, simplifiant le résultat sans impacter le nombre de pas calculés ni le temps d’exécution, qui demeure de 27 pas en 0,0 s. Cette optimisation reflète une utilisation des ressources plus sobre, ce qui est bon et plus respectueux pour notre planète.

Plus sobre peut-être en calculs, mais ça fait aussi un code plus long qu'il faudra transporter. Smiley cligne

Amicalement,
parsimonhi a écrit :
Plus sobre peut-être en calculs, mais ça fait aussi un code plus long qu'il faudra transporter,

C’est vrai. Il y a effectivement 2 octets de plus par « ?: » Smiley ravi On peut donc se demander si ça vaut le coup d’économiser, par exemple, 2 secondes (1 s au lieu de 3) pour l’exécution de la routine précédente avec une chaine de 2117 "A " répétés suivi d’un "A" final.

Sur un site qui ne reçoit que 30 visites par jour, on peut se dire que ce n’est peut-être pas judicieux.

Dans des contextes où chaque milliseconde compte, cette optimisation pourrait être significative. Mais cela soulève une question intéressante sur l’équilibre entre l’optimisation des performances et l’économie de ressources, notamment en termes de taille du code. À quel point peut-on penser que les avantages en termes de performances de stockage et de vitesse justifient une augmentation, même légère, de la taille du code ? Smiley rolleyes

En fait, je me souviens combien j’avais été étonné que Google ne gagnât, c’était il y a bien longtemps, et depuis il fait mieux, qu’une infime fraction de centimes par requête et était déjà l’une des plus grandes fortunes du monde. Donc oui, je crois que cela vaut le coup que chacun ajoute ces 2 octets. Mais bon, c'est un autre débat. Smiley smile
Modifié par Pyanepsion (24 Mar 2024 - 17:53)
Modérateur
Bonjour,

Ralala !

Pyanepsion a écrit :

C’est vrai. Il y a effectivement 2 octets de plus par « ?: » Smiley ravi On peut donc se demander si ça vaut le coup d’économiser, par exemple, 2 secondes (1 s au lieu de 3) pour l’exécution de la routine précédente avec une chaine de 2117 "A " répétés suivi d’un "A" final.
Y en a qui ont 2118 "A" séparés par des espaces dans leurs noms dans ton association ? Et ben !

2 octets, c'est peu, mais le gain de temps d'exécution est faible lui aussi.

Et au lieu de continuer à me "demander", j'ai fait le test (ce que j'avais d'ailleurs préconisé en premier il y a quelques posts quand tu nous demandais ce qu'on en pensait). J'ai donc essayé de gagner 2 secondes en faisant tourner les 2 versions des regex sur un nom qui comporte 2118 "A" séparés par un espace. Il a fallu que je fasse environ 2 millions de fois le test pour que la version avec les ?: finisse par gagner 2 secondes sur la version sans les ?:

Dans la regex avec les ?:, il y a 3 fois ?: soit 6 octets. Si je télécharge ces 6 octets 2 millions de fois (on suppose que 2 millions de visiteurs viennent sur le site vérifier une fois leur nom, et donc télécharger à chaque fois la regex, et faire une fois la comparaison), ça fait environ 12 Mo à télécharger rien que pour les ?:. Selon la connexion, ça va prendre plus ou moins de temps, mais ça sera aussi de l'ordre de quelques secondes.

Et on a quand même pris un cas assez défavorable pour la regex sans les ?:, à savoir 2 millions de gens qui auraient des noms de 4235 octets de long. Je n'en connais pas beaucoup qui ont des noms de cette longueur Smiley lol . Si les noms sont d'une longueur raisonnable, le temps perdu à télécharger des ?: devient vite très supérieur au temps gagné à l'exécution grâce à ces ?: car il faudra faire beaucoup plus de 2 millions de test (et donc beaucoup que 2 millions de téléchargement de la regex) pour gagner les 2 secondes.

Qui l'eut cru !

Amicalement,
parsimonhi a écrit :
Y en a qui ont 2118 "A" séparés par des espaces dans leurs noms dans ton association ?

Tu te bases sur trois suppositions erronées : le contexte d’application, l’objectif de ma recherche, et l’hypothèse que la séquence "A " répétée 2118 fois n’est pas envisageable dans mon scénario. Smiley biggrin

Je trouve par contre ton exploration très intéressante et te remercie pour le temps consacré à cette expérimentation. J’ai de mon côté adopté une posture plus observatrice, utilisant regex101 sans pour autant me lancer dans des tests approfondis, faute de savoir comment établir une boucle réellement significative.

Ton analyse souligne à merveille comment, dans certains cas, des bénéfices apparemment minimes pour un utilisateur individuel peuvent, accumulés, devenir considérables à l’échelle globale. Cela rappelle l’effet papillon des recherches Google, où de minuscules fractions de centimes, multipliées par le nombre colossal de requêtes, nécessitent l’utilisation d’une énergie de plusieurs centrales nucléaires… Une preuve fascinante que les petites optimisations peuvent conduire à des impacts significatifs lorsqu’elles sont adoptées massivement.