如果字符串没有夹在两个令牌之间,则匹配正则表达式

时间:2014-08-28 03:40:51

标签: regex string perl regex-lookarounds

我在使用正则表达式时遇到了麻烦。基本上,我想匹配一个字符串iff在开头和结尾之间没有特定的字符串。让我澄清一下,排除字符串(123),开头(hello)和结束(abc):

hello123abc   ==> no match
helloa123abc  ==> no match
hello123aabc  ==> no match
helloa123aabc ==> no match
hello1abc     ==> match
hello23abc    ==> match
helloaabc     ==> match
helloabc      ==> match

我有一个骨架框架:

=~ m/hello___abc

并尝试使用以下所有内容填写空白:

(?!123).*?
.*?(?!123)
.*?(?!123).*?
(?!123)
(?!123)*?
.*?[^1][^2][^3].*?

以及其他一些我无法记住的组合,但它们都没有奏效。有没有人有办法做到这一点?

4 个答案:

答案 0 :(得分:1)

您可以在这里使用PCRE动词(*SKIP)(*F)

(?:hello.*?123.*?abc)(*SKIP)(*F)|hello.*?abc

DEMO

(?:hello(?:(?!hello).)*123.*?abc)(*SKIP)(*F)|hello.*?abc

DEMO

答案 1 :(得分:1)

我认为你这太难了。

不要只关注你想要匹配的东西(不清楚),而只关注你不喜欢的东西,然后反转逻辑。

假设逐行处理,以下方法可行:

use strict;
use warnings;

while (<DATA>) {
    if (! /hello.*123.*abc/) {
        print "matches  - $_";
    } else {
        print "no match - $_";
    }
}

__DATA__
hello123abc
helloa123abc
hello123aabc
helloa123aabc
hello1abc
hello23abc
helloaabc
helloabc

输出:

no match - hello123abc
no match - helloa123abc
no match - hello123aabc
no match - helloa123aabc
matches  - hello1abc
matches  - hello23abc
matches  - helloaabc
matches  - helloabc

用于捕获的外推答案,而不仅仅是匹配

如果您不想仅仅匹配,而是捕获以hello和abc为界但不包含123的字符串,那么以下内容对您有用:

use strict;
use warnings;

my $data = do {local $/; <DATA>};

while ($data =~ m/(hello(?:(?!123).)*?abc)/g) {
    print "matches - $1\n";
}

__DATA__
hello123abc hello1abc helloa123abchello123aabc
hello23abc helloaabc helloa123aabc helloabc

输出:

matches - hello1abc
matches - hello23abc
matches - helloaabc
matches - helloabc

答案 2 :(得分:0)

一种方法是仅描述两个字符串之间允许的字符(&#34; hello&#34;和&#34; abc&#34;)。为此,您需要排除要禁止的字符串的第一个字符,以及结束子字符串的第一个字符来描述子字符串之间允许的字符:

^hello(?>[^1a]+|1(?!23)|a(?!bc$))*abc$

要在更大的字符串(包含多个&#34; hello&#34; ...&#34; abc&#34;部分)中执行相同操作,您只需删除锚:

hello(?>[^1a]+|1(?!23)|a(?!bc))*abc

答案 3 :(得分:0)

   (?!^hello.*?123)(^.*$)

这样可行。

参见演示..

http://regex101.com/r/uU0hL0/1