处理数字序列的复杂正则表达式



嗨,我遇到了一个很难处理的正则表达式,我对它的了解非常有限。如果有人能让我理解如何解释这样的问题,那就太好了:

说明:给定一个数字字符串,如1234567,我必须想出一个正则表达式,将结果输出为:

12
23
34
45
56
67

我不是要求一个直接的解决方案,而是一个指导方针将是伟大的。

在perl中,您可以:

echo 1234567|perl -ne 's/(?<!^)(.)(?!$)/$1n$1/g; print;'

(?<!^)是一个否定的后备断言(用于字符串^的开头)。(?!$)是否定的前瞻断言(对于字符串$的末尾)。正则表达式将匹配除第一个和最后一个字符之外的所有字符。替换重复匹配的字符,并在中间添加换行符。

您没有说明您使用的是哪种语言,但我认为它支持正向前瞻-大多数都支持。

以下是Java中的一个解决方案:

public static void main(final String[] args) throws Exception {
final String in = "1234567";
final Pattern patt = Pattern.compile("(?=(\d{2})).");
final Matcher matcher = patt.matcher(in);
while (matcher.find()) {
System.out.println(matcher.group(1));
}
}

输出:

12
23
34
45
56
67

模式是(?=(d{2})).(由于语言语法原因,您需要Java中的\)。

说明:

  • (?=(d{2}))这是解决方案的核心,有点棘手,它是一个正向前瞻断言,用于检查输入String中当前点后面的两位数字。然后它获取这两个数字——这就是"输出"的来源
  • .匹配任何字符(也可以是d,但这不是必需的)。这样可以确保正则表达式引擎一次沿着一个空间移动

因此,最初发动机作为String的启动。断言捕获12.捕获并消耗1。现在引擎在1之后,断言捕获23.捕获并消耗2。等等

诀窍是断言一次捕获两个字符,但模式一次只推进一个字符。

这一行执行替换而不是搜索-在Java中,String是不可变的,因此结果实际上是不同的String-操作不会修改String in

public static void main(final String[] args) throws Exception {
System.out.println("1234567".replaceAll("(?=(\d{2})).(?=\d{2})", "$1n"));
}

在这里,我们需要添加另一个断言,即在这个数字之后至少还有两个数字要消费。输出:

12
23
34
45
56
67

这与Perl的一行代码一样好

echo 1234567 | perl -ne "$=$/; print for $_=~/(?=(dd))/g"

正则表达式不会输出任何内容,它会查找匹配的文本。我猜你的"输出"实际上是所有匹配项的列表。

因此,您需要一个正则表达式,它可以在搜索文本中找到所有这些数字对。

最新更新