1
votes

Essayer d'optimiser une regex

Problème

J'essaie d'obtenir une expression régulière qui correspond à [0-9]: [0-9] ou [0-9] ]. [0-9] ou [0-9] ou [0-9]: ou [0-9]. code>

Ce que j'ai essayé

\d+[\.:]*\d*

Cette regex qui satisfait ma condition.

Mon code optimisé

/^\d?(\d+)?((\.|\:|\d)$|(\.|\:|\d)(\d+)?\d$)/

Mais c'est accepter 2: 2: . En fait, ça ne devrait pas. Impossible de résoudre ce problème.


2 commentaires

Essayez ^ \ d + (?: [.:] \ D *)? $ , voir démo .


normalement les regexps se compilent sous une forme optimisée (un automate fini), alors pourquoi essayer de les optimiser vous-même? L'expression que vous avez obtenue dans le premier cas a fonctionné, puis utilisez-la. Il n'y a plus d'efficacité dans le second, c'est plus simple car il correspond à une forme d'entrée plus simple. Comme les deux analysent l'entrée en une seule passe, l'exécution du même algorithme d'automate (à partir de l'état X avec l'entrée Y, aller à l'état Z et accepter ou non), la seule chose qui change est la table utilisée pour l'analyse.


3 Réponses :


1
votes

Que diriez-vous de \ d ([:.] \ d?)? ? Cela devrait gérer tous les cas que vous avez mentionnés.

Ou \ d + ([:.] \ D *?)? si vous voulez accepter plus d'un chiffre dans chaque nombre.

Pour ne correspondre que si elle est exacte, ajoutez simplement ^ au début et $ à la fin de l'expression régulière. Exemple:

const regex = /^\d+([:.]\d*?)?$/

console.log(regex.test('2'))
console.log(regex.test('2:'))
console.log(regex.test('2.'))
console.log(regex.test('2:3'))
console.log(regex.test('2.3'))
console.log(regex.test('12:23'))
console.log(regex.test('23.34'))
console.log(regex.test('2:3:4'))
console.log(regex.test('2.3.4'))


4 commentaires

aucun problème :). Vous n'avez pas besoin du moindre quantificateur de toute façon, n'est-ce pas?


@JamesCoyle J'ai essayé (/\d+([:.[/. J'obtiens le résultat comme vrai. En fait, cela devrait échouer.


C'est parce qu'il l'a trouvé deux fois. Regex.test retournera true si une partie de la chaîne correspond. J'ai édité avec une solution.


Maintenant, il est presque identique à ma solution, tandis que le motif de correspondance de chiffres paresseux \ d *? le rend moins efficace qu'avec un quantificateur gourmand.



1
votes

Votre \ d + [\ .:] * \ d * n'est pas ancré et correspond à des sous-chaînes partielles correspondant au modèle. De plus, il correspond à 11 ..... ::::: comme des chaînes comme [.:] * correspond à 0+ . ou : caractères.

Vous pouvez utiliser

^\d+(?:[.:]\d*)?$

Voir le démo regex .

Détails

  • ^ - début de chaîne
  • \ d + - 1+ chiffres
  • (?: - début d'une correspondance de groupe non capturante
    • [.:] - un . ou :
    • \ d * - 0+ chiffres
  • )? - 1 ou 0 fois
  • $ - fin de chaîne.


1 commentaires

@RinoRaj Bonjour, puis-je demander une faveur? Je pense que cette question a été incorrectement marquée comme dupe . Pourriez-vous s'il vous plaît voter pour la réouverture? (Veuillez ne pas répondre au commentaire, je le supprimerai bientôt.)



0
votes

2: 2 : ne correspond pas complètement, seule la sous-chaîne 2: 2

Pour éviter cela, utilisez simplement les ancres ^ et $ comme vous les avez utilisées dans le modèle d'origine. Voici un exemple de regex fonctionnel utilisant votre expression régulière optimisée avec les ancres ajoutées - /^\d+[.:ITED?\d*$/ , et voici un lien vers celui-ci https://regexr.com/47msc


0 commentaires