正则表达式逗号分隔的单个数字按升序排列

Regex comma separated single digits ordered ascending

我正在尝试编写一个正则表达式来验证具有以下条件的用户输入(asp.net,c#):

- single digits within a range of 1 - 6
- comma separated, but list should not begin or end with a comma
- digits cannot be repeated
- digits should be in ascending order

例如:

- 1,2,3,4,5,6   - valid
- 2,5,6         - valid
- 4             - valid
- 2,5,6,        - invalid
- 3,6,5         - invalid
- 2,2,5,6       - invalid

到目前为止我有:

^((1,)?(2,)?(3,)?(4,)?(5,)?(6)?)$

问题是数字 1-5 后面必须跟一个逗号,如果它们是唯一输入的数字,则不正确。

您可以使用 \b 来确保您处于单词的边界,并使用 ,* 来有逗号或没有逗号。这导致工作 - 尽管相当长

^((1)?(\b,?2)?(\b,?3)?(\b,?4)?(\b,?5)?(\b,?6)?)$

(这是一个愚蠢的答案)

鉴于有六个值,每个值都可以存在或不存在,因此有 2^6 = 64 个可能的正确值;除了我猜我们想排除根本没有数字存在的可能性,所以只有 63 可能的正确值。此正则表达式允许它们且仅允许它们:

^(6|5|5,6|4|4,6|4,5|4,5,6|3|3,6|3,5|3,5,6|3,4|3,4,6|3,4,5|3,4,5,6|2|2,6|2,5|2,5,6|2,4|2,4,6|2,4,5|2,4,5,6|2,3|2,3,6|2,3,5|2,3,5,6|2,3,4|2,3,4,6|2,3,4,5|2,3,4,5,6|1|1,6|1,5|1,5,6|1,4|1,4,6|1,4,5|1,4,5,6|1,3|1,3,6|1,3,5|1,3,5,6|1,3,4|1,3,4,6|1,3,4,5|1,3,4,5,6|1,2|1,2,6|1,2,5|1,2,5,6|1,2,4|1,2,4,6|1,2,4,5|1,2,4,5,6|1,2,3|1,2,3,6|1,2,3,5|1,2,3,5,6|1,2,3,4|1,2,3,4,6|1,2,3,4,5|1,2,3,4,5,6)$

请不要实际使用它。你会让我们都难看。

非正则表达式版本。简单精确

string str = ",1,  2,3, 4, 5, 6";
bool valid = false;
var invalidString = str.Split(',').Any(p =>
{
    int num = 0;
    return int.TryParse(p, out num);
});
if (!invalidString)
{
    List<int> list = str.Split(',').Select(p => int.Parse(p)).ToList();
    var sorted = list.SequenceEqual(list.OrderBy(p => p));
    var hasDuplicates = list.Count != list.Distinct().Count();
    valid = sorted && !hasDuplicates;
}

严格出于学习目的,将问题分解成小块。

它必须由一个数字组成,后跟零个或多个逗号加数字。

^\d(?:,\d)*$

只有6位数字,必须按升序排列。因此,只需列出它们及其中间的逗号即可;每个都是可选的。

^1?,?2?,?3?,?4?,?5?,?6?$

难点在于以上两个正则表达式必须同时匹配。我们可以对其中之一使用零宽度前瞻。这将匹配但不会 "consume" 任何字符。因此,在它匹配正则表达式的下一段后,它将从与前瞻相同的位置开始。向前看是通过在 (?= 和 ')' 中包装一个表达式来实现的。给予:

(?=^\d(?:,\d)*$)

结合两个正则表达式得到以下结果:

(?=^\d(?:,\d)*$)^1?,?2?,?3?,?4?,?5?,?6?$