Какому регулярному выражению, которое я могу использовать для поиска всех строк bar
, не предшествует строка foo
? Наличие пробела между ними также является незаконным.
Поэтому регулярное выражение должно соответствовать следующим строкам
foo is bar hello bar
Но не эти
foobar foo bar
Я пробовал использовать следующие
(?!<foo)bar
и он получает работу, сделанную для устранения foobar
, но мне нужно позаботиться о пробелах и, конечно же,
(?!<foo)\s*bar
соответствует всем строкам.
Благодаря!
Лучше использовать другие возможности языка программирования, чем выглядеть слишком сложно для шаблона регулярных выражений.
Вы ищете строки, для которых $s =~ /bar/ and not $s =~ /foo\s*bar/
истинно.
Остальная часть приведенного ниже сценария предназначена только для тестирования.
#!/usr/bin/perl use strict; use warnings; my %strings = ( 'foo is bar' => 1, 'hello bar' => 1, 'foobar' => 0, 'foo bar' => 0, 'barbar' => 1, 'bar foo' => 1, 'foo foo' => 0, ); my @accept = grep { $strings{$_} } keys %strings; my @reject = grep { not $strings{$_} } keys %strings; for my $s ( @accept ) { if ( $s =~ /bar/ and not $s =~ /foo\s*bar/ ) { print "Good: $s\n"; } else { print "Bad : $s\n"; } } for my $s ( @reject ) { if ( $s =~ /bar/ and not $s =~ /foo\s*bar/ ) { print "Bad : $s\n"; } else { print "Good: $s\n"; } }
Вывод:
E: \ srv \ unur> j Хорошо: bar foo Хорошо: привет Хорошо: foo является баром Хорошо: barbar Хорошо: foo foo Хорошо: foo bar Хорошо: foobar
Учитывая несколько тестовых примеров
my @match = ( "foo is bar", "hello bar", ); my @reject = ( "foobar", "foo bar", );
вы, конечно, можете сделать, подав результаты одного шаблона другому:
my @control = grep !/foo\s*bar/, grep /bar/ => @match, @reject;
Мы также можем сделать это с одним:
my $nofoo = qr/ ( [^f] | f (?! o) | fo (?! o \s* bar) )* /x; my $pattern = qr/^ $nofoo bar /x;
Но не верьте мне на слово.
for (@match) { print +(/$pattern/ ? "PASS" : "FAIL"), ": $_\n"; } for (@reject) { print +(/$pattern/ ? "FAIL" : "PASS"), ": $_\n"; }
(?!<foo)\s*bar
Это будет соответствовать пробелу
PHP:
!preg_match(/foo\s*bar/,$string) && preg_match(/bar/,$string)
Perl:
$string !~ /foo\s*bar/ && $string =~ /bar/
Принимая информацию из более ранних ответов, обертывая как однострочный perl, и делая регулярные выражения без учета регистра.
Окна:
perl -lne "print $_ if $_ !~ m/foo\s*bar/i && $_ =~ m/bar/i;" c:\temp\xx.txt
Linux:
perl -lne 'print $_ if $_ !~ m/foo\s*bar/i && $_ =~ m/bar/i;' /tmp/xx.txt
С xx.txt, содержащим:
foo is bar hello bar foobar foo bar barbar bar foo barfoo foo foo
Результат выполнения однострочного в командной строке:
foo is bar hello bar barbar bar foo barfoo