我正在尝试使用正则表达式从10位数字中获取所有可能的连续4位数字。喜欢
num = "2345678901";
输出
2345
,3456
,4567
,5678
,6789
,7890
,8901
这些简单的正则表达式不起作用:
[\d]{4}
(\d\d\d\d)
答案 0 :(得分:7)
您需要使用(?=(\d{4}))
正则表达式匹配重叠匹配。
请参阅regex demo
您正在使用的正则表达式都消耗了4位数的文本块,因此重叠值不匹配。使用(?=...)
正向前瞻,您可以在输入字符串中测试每个位置,并从这些位置捕获 4个数字块,而不用消费字符(即没有将正则表达式引擎指针移动到这4个数字块之后的位置)。
var data = "2345678901";
var res = Regex.Matches(data, @"(?=(\d{4}))")
.Cast<Match>()
.Select(p => p.Groups[1].Value)
.ToList();
Console.WriteLine(string.Join("\n", res));
答案 1 :(得分:2)
你绝对需要使用正则表达式吗?使用简单的循环可以更快地实现相同的操作。
private IEnumerable<string> getnums(string num)
{
for (int i = 0; i < num.Length - 3; i++)
{
yield return num.Substring(i, 4);
}
}
private IEnumerable<string> DoIt(string num)
{
var res = Regex.Matches(num, @"(?=(\d{4}))")
.Cast<Match>()
.Select(p => p.Groups[1].Value)
.ToList();
return (IEnumerable<string>)res;
}
平均而言,简单循环大约需要RegEx版本的一半时间。
static void Main(string[] args)
{
var num = "2345678901";
Stopwatch timer = new Stopwatch();
timer.Start();
foreach (var number in getnums(num))
{
// Yum yum numbers
}
timer.Stop();
Console.WriteLine(timer.Elapsed.Ticks);
timer.Reset();
timer.Start();
foreach (var number in DoIt(num))
{
// Yum yum numbers
}
timer.Stop();
Console.WriteLine(timer.Elapsed.Ticks);
}