在某些正则表达式中,不支持[负]零宽度断言(前瞻/后瞻)。
这使得排除很难(不可能?)。例如“不的每一行都有”foo“,就像这样:
^((?!foo).)*$
可以在不使用外观的情况下实现同样的目标(暂时留出的复杂性和性能问题)?
答案 0 :(得分:30)
更新:它失败了“在oo之前有两个ff”为@Ciantic pointed out in the comments.
^(f(o[^o]|[^o])|[^f])*$
注意:只是在客户端取消匹配而不是使用上述正则表达式要容易得多。
正则表达式假设每行都以换行符结尾,如果不是,则查看C ++和grep的正则表达式。
Perl,Python,C ++和grep
中的示例程序都提供相同的输出。
#!/usr/bin/perl -wn
print if /^(f(o[^o]|[^o])|[^f])*$/;
#!/usr/bin/env python
import fileinput, re, sys
from itertools import ifilter
re_not_foo = re.compile(r"^(f(o[^o]|[^o])|[^f])*$")
for line in ifilter(re_not_foo.match, fileinput.input()):
sys.stdout.write(line)
C ++
#include <iostream>
#include <string>
#include <boost/regex.hpp>
int main()
{
boost::regex re("^(f(o([^o]|$)|([^o]|$))|[^f])*$");
//NOTE: "|$"s are there due to `getline()` strips newline char
std::string line;
while (std::getline(std::cin, line))
if (boost::regex_match(line, re))
std::cout << line << std::endl;
}
$ grep "^\(f\(o\([^o]\|$\)\|\([^o]\|$\)\)\|[^f]\)*$" in.txt
示例文件:
foo
'foo'
abdfoode
abdfode
abdfde
abcde
f
fo
foo
fooo
ofooa
ofo
ofoo
输出:
abdfode
abdfde
abcde
f
fo
ofo
答案 1 :(得分:1)
您通常可以查找foo并从客户端代码中反转正则表达式匹配的结果。
举一个简单的例子,假设您要验证字符串是否只包含某些字符。
你可以这样写:
^[A-Za-z0-9.$-]*$
并接受true
结果为有效,或者像这样:
[^A-Za-z0-9.$-]
并接受false
结果为有效。
当然,这并不总是一个选项:例如,有时您只需将表达式放在配置文件中或将其传递给另一个程序。但值得记住。 您的具体问题,例如,如果您可以使用这样的否定,表达式很多更简单。
答案 2 :(得分:1)
我偶然发现了这个问题,寻找我自己的正则表达式排除解决方案,我试图在我的正则表达式中排除序列。
我对这种情况的初步反应:例如“每条没有”foo“的行”只是在grep中使用-v invert sense of matching选项。
grep -v foo
这将返回文件中与'foo'
不匹配的所有行这很简单,我有强烈的感觉,我只是误解了你的问题......