我正在使用正则表达式来查找:
test:?
跟随任何字符,直到它到达下一个:
test:?
现在当我运行这个正则表达式时,我做了:
((?:test:\?)(.*)(?!test:\?))
在这篇文章中:
test:?foo2=bar2&baz2=foo2test:?foo=bar&baz=footest:?foo2=bar2&baz2=foo2
我希望得到:
test:?foo2=bar2&baz2=foo2
test:?foo=bar&baz=foo
test:?foo2=bar2&baz2=foo2
但它匹配一切。有更多正则表达式经验的人知道我哪里出错吗?我以前曾使用正则表达式进行模式匹配,但这是我第一次看到前瞻/未来的经历。
提前感谢任何帮助/提示/指示: - )
答案 0 :(得分:4)
我想你可以探索一个贪婪的版本 (膨胀)
(test:\? (?: (?!test:\?)[\s\S])* )
答案 1 :(得分:2)
下面的Perl程序
#! /usr/bin/env perl
use strict;
use warnings;
$_ = "test:?foo2=bar2&baz2=foo2test:?foo=bar&baz=footest:?foo2=bar2&baz2=foo2";
while (/(test:\? .*?) (?= test:\? | $)/gx) {
print "[$1]\n";
}
从您的问题产生所需的输出,加上括号以强调。
[test:?foo2=bar2&baz2=foo2] [test:?foo=bar&baz=foo] [test:?foo2=bar2&baz2=foo2]
请记住regex quantifiers are greedy,并希望尽可能地吞噬,而不会破坏比赛。每个子段尽快终止,这意味着.*?
语义。
每个子细分都以另一个test:?
或字符串结尾终止,我们通过(?=...)
零宽度前瞻搜索|
来寻找替代方案。
上面代码中的模式使用Perl’s /x
regex switch来提高可读性。根据您使用的语言和库,您可能需要删除额外的空格。
答案 2 :(得分:0)
三个问题:
(?!)
是一个负面的先行断言。您需要(?=)
,要求接下来的内容是test:?
。
.*
贪婪;你希望它不贪婪,以便你只抓住第一块。
你也想要最后一个块,所以你想在最后匹配$
。
最终结果:
(?:test:\?)(.*?)(?=test:\?|$)
我也删除了外部组,没有任何意义。我所知道的所有RE引擎都允许您将组0作为完全匹配或其他一些方式访问(尽管可能不是在找到所有匹配时)。如果需要,你可以把它放回去。
(这适用于PCRE;不确定它是否适用于POSIX正则表达式,因为我不习惯使用它们。)
如果您只是想要在test:?
上拆分,那么正则表达式是错误的工具。使用您的语言内置支持来拆分字符串。
的Python:
>>> re.findall('(?:test:\?)(.*?)(?=test:\?|$)',
... 'test:?foo2=bar2&baz2=foo2test:?foo=bar&baz=footest:?foo2=bar2&baz2=foo2')
['foo2=bar2&baz2=foo2', 'foo=bar&baz=foo', 'foo2=bar2&baz2=foo2']
答案 3 :(得分:-1)
你可能想要((?:test:\?)(.*?)(?=test:\?))
,虽然你还没有告诉我们你用什么语言来驱动正则表达式。
.*?
匹配尽可能少的字符而不会阻止整个字符串匹配,其中.*
匹配尽可能多的(是贪婪)。
再次,根据您使用的语言,您可能需要匹配,然后切断字符串,然后再次匹配,或调用某些特定于语言的match_all类型函数。
顺便说一下,你不需要使用前瞻来锚定正则表达式(你可以匹配模式来搜索,所以这将(很可能)在你的情况下做:
test:[?](.*?)test:[?]