Désolé pour le titre déroutant, je vais essayer de l'expliquer avec un exemple. Actuellement, nous avons cette expression pour trouver une séquence de nombres dans une chaîne
\b((\d[ ]{0,1}){13,19})\b
Maintenant, j'aimerais le modifier pour qu'il réponde à ces règles
- La longueur doit être comprise entre 13 et 19 caractères, à l'exclusion des espaces
- Chaque groupe de numéros doit avoir au moins 3 chiffres

L'expression doit les marquer comme correspondant:

1234567890123
1234 5678 9012 345

Ne correspond pas:

123456789012 3
123 12 123 1 23134

L'expression actuelle que j'ai les marquera tous comme correspondant.
Exemple

2
Eka T 2 août 2017 à 12:01

2 réponses

Meilleure réponse

Ceci est possible en utilisant le look-around.

Le regex peut être changé comme suit:

\b(?<!\d )(?=(?:\d ?){13,19}(?! ?\d))(?:\d{3,} ?)+\b(?! ?\d)

Cela fonctionne en regardant vers l'avant pour s'assurer que le nombre comporte entre 13 et 19 chiffres. Il correspond ensuite à des groupes de 3 chiffres ou plus. Il utilise ensuite une analyse négative après avoir trouvé tous les groupes de 3 pour s'assurer qu'il ne reste plus aucun nombre. S'il y en a, nous avons trouvé un groupe inférieur à 3. Cela fonctionne sur les exemples que vous avez fournis.

  • \b S'assure que c'est le début d'un "mot".
  • (?<!\d ) Assurez-vous qu'il n'y a pas de chiffres derrière.
  • (?=(?:\d ?){13,19}(?! ?\d)) regarde devant pour s'assurer que le numéro comporte entre 13 et 19 chiffres
    • (?:\d ?){13,19} De l'original. ?: ajouté pour ne pas capturer
    • (?! ?\d) Perspectives négatives: s'il reste encore des chiffres après avoir obtenu 19 chiffres, ils sont trop gros, alors supprimez la correspondance actuelle
  • (?:\d{3,} ?)+ Correspond à n'importe quel nombre de clusters supérieur à 3 (min 13, max 19 traités par premier aperçu)
  • \b(?! ?\d) Recherche la fin d'un cluster. S'il reste encore des nombres après la fin du cluster, il doit y avoir un cluster trop petit.

Testez ici

3
Kaamil Jasani 2 août 2017 à 15:53

Si vous pouvez utiliser Linq, ce sera beaucoup plus facile à maintenir:

var myList = new List<string>
                    {
                    "1234567890123",
                    "1234 5678 9012 345",
                    "123456789012 3",
                    "123 12 123 1 23134"
                    };

foreach(var input in myList)
{
    var splitted = Regex.Split(input, @"\s+"); // Split on whitespace

    var length = splitted.Sum(x => x.Length); // Compute the total length
    var smallestGroupSize = splitted.Min(x => x.Length); // Compute the length of the smallest chunck
    Console.WriteLine($"Total lenght: {length}, smallest group size: {smallestGroupSize}");

    if (length < 13 || length > 19 || smallestGroupSize < 3)
    {
        Console.WriteLine($"Input '{input}' is incorrect{Environment.NewLine}");
        continue;
    }

    Console.WriteLine($"Input '{input}' is correct!{Environment.NewLine}");
}

Qui produit:

Longueur totale: 13, taille de groupe la plus petite: 13 L'entrée «1234567890123» est correcte!

Longueur totale: 15, taille de groupe la plus petite: 3 L'entrée «1234 5678 9012 345» est correcte!

Longueur totale: 13, taille de groupe la plus petite: 1 L'entrée «123456789012 3» est incorrecte

Longueur totale: 14, taille de groupe la plus petite: 1 L'entrée «123 12123 1 23134» est incorrecte

0
Thomas Ayoub 2 août 2017 à 12:36