Je voudrais faire correspondre une chaîne en trois parties. La première partie se compose d'un ou plusieurs a caractères, la deuxième partie se compose d'un ou plusieurs b caractères et la troisième partie se compose de zéro ou plusieurs c caractères ou zéro ou plus C caractères, mais pas un mélange de c et C.

En tant que tel, j'ai écrit l'expression régulière suivante:

/a+b+(C*|c*)/

Et immédiatement remarqué qu'il ne parvient pas à faire correspondre avidement les c finaux dans la chaîne suivante:

aaaaabbcc

L'encapsulation des clauses internes de la clause or ne résout pas le comportement inattendu:

/a+b+((C*)|(c*))/

Mais il est intéressant de noter que les deux expressions régulières correspondent à ce qui suit, où les caractères C correspondent à la première clause de ou:

aaaaabbCC

L'expression régulière suivante capture la sémantique avec précision, mais j'aimerais comprendre pourquoi l'expression régulière d'origine se comporte de manière inattendue.

/a+b+(([Cc])\2*)?/
2
skeggse 7 août 2016 à 23:37

3 réponses

Meilleure réponse

Votre expression régulière ne fonctionne pas car elle essaie d'abord C*, qui correspond à la chaîne vide, donc elle a satisfait la clause or. Ensuite, il n'essaiera pas de vérifier si c* peut correspondre à plus de caractères.

Voici une expression régulière qui correspond à la chaîne comme prévu:

/a+b+(C+|c+)?/

Autrement dit, s'il trouve un C, il correspondra à autant de C que possible, s'il trouve un c, il correspondra à autant de c que possible. Mais trouver C ou c est facultatif.

5
skeggse 7 août 2016 à 21:52
var input = "aaaaabbc";

// if you want to pick up c
console.log(/a+b+(c|C)*/.exec(input).pop());
1
Hitmands 7 août 2016 à 20:42

Vous devez placer le * à l'extérieur du support!

2
csabinho 7 août 2016 à 20:42