我想匹配任何只包含增加或减少数字的字符串。这意味着这些字符串将匹配:
123, 234567, 0123456789, 87654, 321
这些不会:
7891011, 1234566789, 987865, 134
我一直在寻找答案,all I found是使用正则表达式无法完成的。但是,我想在正则表达式中执行此操作,否则会在代码中弄乱。
感谢您的回答。
答案 0 :(得分:5)
从技术上讲,可以使用前瞻,但看起来不太好。
提升模式的逻辑:
123的例子:
134的例子:
正则表达式匹配升序模式:
^(?: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?$
结合在一起:
^((?: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?)$
答案 1 :(得分:1)
代码不会比正则表达式更糟糕。正则表达式在数学上很糟糕。
这样的事情会做到:
bool IsSequentiallyIncreasing(string input)
{
char? lastDigit = null;
foreach (char c in input)
{
if (!c.IsDigit || (lastDigit != null && c != lastDigit + 1))
{
return false;
}
lastDigit = c;
}
return true;
}
所以你走过字符串中的所有字符,一旦遇到非数字或不是最后一位数字+ 1的数字,你就会返回false。
为减少而做同样的事情,你只需拨打IsSequentiallyIncreasing(input) || IsSequentiallyDecreasing(input)
即可。我将由您来添加错误处理并将两种方法合并为一种。
答案 2 :(得分:1)
我创建了一个函数IsSequential
:
static bool IsSequential(string 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;
}
然后只需检查每个号码IsSequential
,或者IsSequential
是否反转。
var inputs = @"123, 234567, 0123456789, 87654, 321, 7891011, 1234566789, 987865";
var valids = inputs
.Split(',')
.Select(n => n.Trim())
.Where(n => IsIncreasing(n) || IsIncreasing(new string(n.Reverse().ToArray())))
.ToList();
如果您需要将它们精确地增加1,请使用if(num != last+1)
答案 3 :(得分:1)
没有可以执行此操作的正则表达式模式,但您可以使用正则表达式来帮助收集这些项目
List<Match> oMatches = new List<Match>();
String 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
});