Je voudrais faire correspondre toute chaîne qui contient uniquement des chiffres qui augmentent ou diminuent. Cela signifie que ces chaînes seraient appariées:
123, 234567, 0123456789, 87654, 321
Et ceux-ci ne seraient pas:
7891011, 1234566789, 987865, 134
Je cherchais une réponse et tout ce que j’ai trouvé, c’est qu’il est impossible de le faire avec regex. Cependant, je voudrais le faire en regex, sinon cela créerait un désordre dans le code.
Merci pour les réponses.
Techniquement, cela est possible avec l’utilisation de lookaheads, mais cela ne sera pas beau.
Logique pour motif ascendant:
Exemple pour 123:
Exemple pour 134:
Regex pour correspondre aux modèles ascendants:
^(?:0(?=1|$))?(?:1(?=2|$))?(?:2(?=3|$))?(?:3(?=4|$))?(?:4(?=5|$))?(?:5(?=6|$))?(?:6(?=7|$))?(?:7(?=8|$))?(?:8(?=9|$))?9?$
Démo Debuggex
Regex pour correspondre aux modèles décroissants:
^(?:9(?=8|$))?(?:8(?=7|$))?(?:7(?=6|$))?(?:6(?=5|$))?(?:5(?=4|$))?(?:4(?=3|$))?(?:3(?=2|$))?(?:2(?=1|$))?(?:1(?=0|$))?0?$
Démo Debuggex
Combinés ensemble:
^((?:0(?=1|$))?(?:1(?=2|$))?(?:2(?=3|$))?(?:3(?=4|$))?(?:4(?=5|$))?(?:5(?=6|$))?(?:6(?=7|$))?(?:7(?=8|$))?(?:8(?=9|$))?9?|(?:9(?=8|$))?(?:8(?=7|$))?(?:7(?=6|$))?(?:6(?=5|$))?(?:5(?=4|$))?(?:4(?=3|$))?(?:3(?=2|$))?(?:2(?=1|$))?(?:1(?=0|$))?0?)$
Démo Debuggex
Regex101 Demo
Le code ne serait pas plus un désordre que la regex pour faire cela. Les expressions régulières sont mauvaises en maths.
Quelque chose comme ça va le faire:
bool IsSequentiallyIncreasing(ssortingng input) { char? lastDigit = null; foreach (char c in input) { if (!c.IsDigit || (lastDigit != null && c != lastDigit + 1)) { return false; } lastDigit = c; } return true; }
Ainsi, vous passez en revue tous les caractères de la chaîne et dès que vous rencontrez un non-chiffre ou un chiffre qui n’est pas le dernier chiffre + 1, vous retournez false.
Et faites de même pour décroissant, et vous pouvez simplement appeler IsSequentiallyIncreasing(input) || IsSequentiallyDecreasing(input)
IsSequentiallyIncreasing(input) || IsSequentiallyDecreasing(input)
. Je vous laisse le soin d’append le traitement des erreurs et de fusionner les deux méthodes en une.
il n’y a pas de motif regex qui puisse le faire, mais vous pouvez utiliser regex pour aider à collecter ces éléments
List oMatches = new List (); Ssortingng sData = "123, 234567, 0123456789, 87654, 321 , 7891011, 1234566789, 987865"; Regex.Replace(sData, @"\d+", delegate(Match oMatch)//delegate is run for each match as closure { char? oLast = null; foreach (char oChar in oMatch.Value)//for each char { if ((oLast != null && Math.Abs(oChar - oLast) > 1))//not in sequense return oMatch.Value;//early return oLast = oChar; } oMatches.Add(oMatch)//add to outside collection return oMatch.Value; //return match itself because we don't actually want to replace anything });
Je IsSequential
une fonction IsSequential
:
static bool IsSequential(ssortingng input) { var nums = input.Select(Convert.ToInt32); int last = nums.First(); foreach (var num in nums.Skip(1)) { if (num < last) return false; last = num; } return true; }
il suffit ensuite de vérifier si chaque nombre est IsSequential
ou s'il est inversé.
var inputs = @"123, 234567, 0123456789, 87654, 321, 7891011, 1234566789, 987865"; var valids = inputs .Split(',') .Select(n => n.Trim()) .Where(n => IsIncreasing(n) || IsIncreasing(new ssortingng(n.Reverse().ToArray()))) .ToList();
si vous souhaitez qu’ils augmentent exactement de 1, utilisez if(num != last+1)