嗨,我一直处理一个困难的正则表达式来处理我的知识非常有限。如果有人能让我理解如何解释这样的问题,那就太棒了:
描述:
给定一串数字,如1234567
,我将得出一个正则表达式,将结果输出为:
12
23
34
45
56
67
我不是要求直接解决方案,而是指南会很棒。
答案 0 :(得分:1)
你没有说明你正在使用哪种语言,但我认为它支持积极的前瞻 - 大多数都是这样做的。
以下是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})", "$1\n"));
}
这里我们需要添加另一个断言,即在此之后至少要再消耗两个数字。输出:
12
23
34
45
56
67
答案 1 :(得分:1)
在perl中,您可以:
echo 1234567|perl -ne 's/(?<!^)(.)(?!$)/$1\n$1/g; print;'
(?<!^)
是negative look-behind assertion(用于字符串^
的开头)。
(?!$)
是一个负面的前瞻断言(对于字符串$
的结尾)。正则表达式将匹配除第一个和最后一个之外的所有字符。替换重复匹配的字符,中间有换行符。
答案 2 :(得分:1)
这与Perl one liner一样:
echo 1234567 | perl -ne "$\=$/; print for $_=~/(?=(\d\d))/g"
答案 3 :(得分:0)
正则表达式不会输出任何内容,它会找到匹配的文本。我猜你的'输出'实际上是所有比赛的列表。
所以你需要一个能在搜索文本中找到所有这些数字对的正则表达式。