从 10 位数字中获取所有可能的连续 4 位数字
Posted
技术标签:
【中文标题】从 10 位数字中获取所有可能的连续 4 位数字【英文标题】:Getting all possible consecutive 4 digit numbers from a 10 digit number 【发布时间】:2017-09-14 08:22:36 【问题描述】:我正在尝试制作一个正则表达式以从 10 位数字中获取所有可能的连续 4 位数字。喜欢
num = "2345678901";
输出:
2345
、3456
、4567
、5678
、6789
、7890
、8901
这些简单的正则表达式不起作用:
[\d]4
(\d\d\d\d)
【问题讨论】:
【参考方案1】:您需要使用(?=(\d4))
正则表达式来匹配重叠的匹配项。
见regex demo
您使用的正则表达式都在消耗 4 位文本块,因此重叠值不匹配。使用(?=...)
正向前瞻,您可以测试输入字符串中的每个 位置,并从这些位置捕获 4 位块,而无需消耗字符(即不将正则表达式引擎指针移动到这 4 位数字块之后的位置)。
C# demo:
var data = "2345678901";
var res = Regex.Matches(data, @"(?=(\d4))")
.Cast<Match>()
.Select(p => p.Groups[1].Value)
.ToList();
Console.WriteLine(string.Join("\n", res));
【讨论】:
这实际上与所需的结果不匹配,但匹配每个组合并将其放入该匹配的捕获组中......是的,它有效,我认为没有前瞻是不可能的,但我认为这是值得注意的。 @ThomasWeller:(?=...)
是一个积极的前瞻,一个零宽度的断言,一个让我们检查(或强制)某些字符存在的构造 after字符串中的当前位置。 Bikonja:我将我的结果与预期的结果进行了比较,它们是相同的。
@Koder101:正则表达式!= 正则表达式。它们有不同的种类。该问题不应同时标记为 .NET 和 Notepad++,因为这相互矛盾。
@Koder101 查看我的评论以获取答案。 Notepad++ 不知道(在查找中,仅在替换中)匹配中的捕获组,因此工作的 C# 代码,但不工作的 Notepad++ 正则表达式。我认为这在 Notepad++ 中是不可能的。
@Koder101:在 Notepad++ 中,使用 (?=(\d4))
并替换为 \nOVERLAPPED: $1\n
。然后,用^OVERLAPPED:\h*\d4$
正则表达式为重叠的行添加书签,将所有添加书签的行复制到一个新文件并删除“OVERLAPPED:”。这不是直截了当的,但有可能。【参考方案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, @"(?=(\d4))")
.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);
【讨论】:
很好的比较,感谢您的方法。如果我回答你的问题,是的,有必要使用正则表达式。因为这个问题只是某些任务的一小部分,实际上我正在处理 - 1. 1000 位长的数字。 2. 实际要求是得到所有可能的 13 位数字,没有零。所以我修改后的正则表达式将是 - @"(?=([1-9]13))" 3. 然后用这些数字做一些任务。我选择使用 Regex 的原因是因为它提供的灵活性和关注点分离。以上是关于从 10 位数字中获取所有可能的连续 4 位数字的主要内容,如果未能解决你的问题,请参考以下文章
屏蔽除字符串的前 6 位和后 4 位之外的所有数字(长度不同)