Étant donné une plage de nombres de 1 à 30, un utilisateur est autorisé à sélectionner n'importe quel nombre de valeurs sans répétition entre 1 et 30, j'essaie d'écrire une expression régulière pour trouver les entrées valides et invalides.
var input = "1,12,30";
Regex regex = new Regex("([1-3][1-1],[1-3][1-1])+");
if(regex.IsMatch(input))
{
Console.WriteLine("Input is in correct format");
}
Par exemple:
4,78,6 n'est pas valide
2,6,24 est valide
Que dois-je changer mon expression régulière en tant que?
4 Réponses :
Regex est un outil de traitement de texte pour faire correspondre les modèles dans les langues régulières. Il est très faible en matière de sémantique. Il ne peut pas identifier la signification dans la chaîne donnée. Comme dans votre condition donnée, pour vous conformer à la condition Donc, vous utilisez un mauvais outil. Regex ne peut pas vous aider ici. Ou même si vous obtenez une solution, ce sera trop complexe et trop difficile à développer. La meilleure façon est de 1 , vous devez avoir la connaissance de leurs valeurs numériques. Split la chaîne sur virgule, puis comparez les nombres. p> var numbers = input
.Split(',') // split to an enumerable of strings
.Select(int.Parse) // transform to an enumerable of numbers
.ToArray(); // Creates an array from a IEnumerable<int>
return numbers.All(x => x > 0 && x <= 30) // range check
&& numbers.Length == numbers.Distinct().Length; // uniqueness check
il serait plus approprié d'utiliser Linq pour valider;
static bool IsValid(string input)
{
var strings = input.Split(",");
if (strings.Any(n => int.Parse(n) <= 0 || int.Parse(n) >= 31)) return false;
return new HashSet<string>(strings).Count == strings.Length;
}
ou mieux créer votre propre fonction personnalisée.
var isValid = input.Split(",")
.GroupBy(s => s)
.Select(g => new { Num = int.Parse(g.Key), Count = g.Count() })
.All(e => e.Count == 1 && e.Num > 0 && e.Num < 31);
Vous n'avez pas besoin de regex pour ce travail Vous pouvez essayer ceci
List<int> inputs = new List<int>();
//make sure the number in range
if(input > 0 && input < 31){
//if there's another input would be added into list so make sure not equal the previous one
if(inputs.count() > 0){
if(input != inputs.Any()){
inputs.Add(input);
}
}
else{
inputs.Add(input)
}
Désolé, il n'a pas testé le code mais peut vous aider
Vous pouvez le faire sans expression régulière, mais comme réponse à votre question dans votre expression régulière, [1-3] [1-1] correspond à 11, 21 ou 31, donc vous correspondez à un motif répétitif de par exemple 31,1121,11.
Si vous voulez faire cela en utilisant une expression régulière, vous pouvez utiliser un modèle (?: [1-9] | [12] \ d | 30) code > pour correspondre à un nombre de 1 à 30, puis répétez ce modèle 0+ fois précédé d'une virgule.
Si ce format correspond, utilisez la division et vérifiez si le nombre d'éléments est égal à la version distincte.
Par exemple:
string pattern = @"^(?:[1-9]|[12]\d|30)(?:,(?:[1-9]|[12]\d|30))*$";
var input = "1,12,30";
List<String> a = input.Split(',').ToList();
Console.WriteLine(Regex.Match(input, pattern).Success && a.Count == a.Distinct().Count()); // True
Voir la Démo C # | Démo Regex
une regex ne serait pas le meilleur outil pour ce travail.
Vous pouvez utiliser
input.Split (','). All (x => Int32.Parse (x)> 0 && Int32.Parse (x) <31)sans répétition entre 1 et 30, donc chaque numéro une seule fois?Diriez-vous que
30,29,28est valide même s'ils ne sont pas dans le bon ordre? Et est-ce que1,1,10serait invalide parce qu'il y a des instances dupliquées de1?