Başka belirli bir kelime öncesinde değil bir kelime bulmak nasıl?

5 Cevap php

Hangi düzenli ifade I bar dize önünde değil tüm dizeleri bulmak için kullanabileceğiniz foo? İkisi arasındaki boşluk olması da yasaktır.

Yani regex aşağıdaki dizeleri aynı olmalıdır

foo is bar
hello bar

Ama bu

foobar
foo     bar

Ben şu kullanarak denedim

(?!<foo)bar

ve foobar ortadan kaldırılması için yapılan iş alır, ama ben boşluğa dikkat çekmek gerekir, ve tabii

(?!<foo)\s*bar

Tüm dizeleri eşleşir.

Teşekkürler!

5 Cevap

Daha iyi bir regex desen için çok zor bakmak daha programlama dilinin diğer imkanları kullanmak.

Sen $s =~ /bar/ and not $s =~ /foo\s*bar/ true olduğu için dizeleri arıyoruz.

Aşağıdaki script kalanı sadece test içindir.

#!/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";
    }
}

Çıktı:

E:\srv\unur> j
Good: bar foo
Good: hello bar
Good: foo is bar
Good: barbar
Good: foo foo
Good: foo     bar
Good: foobar

Birkaç test durumları göz önüne alındığında,

my @match = (
  "foo is bar",
  "hello bar",
);

my @reject = (
  "foobar",
  "foo     bar",
);

Eğer tabii başka bir desen sonuçlarını besleyerek yapabilirsiniz:

my @control = grep !/foo\s*bar/, grep /bar/ => @match, @reject;

Biz de biri ile yapabilirsiniz:

my $nofoo = qr/
  (      [^f] |
    f  (?! o) |
    fo (?! o  \s* bar)
  )*
/x;

my $pattern = qr/^ $nofoo bar /x;

Ama bunun için sözümü yapmayız.

for (@match) {
  print +(/$pattern/ ? "PASS" : "FAIL"), ": $_\n";
}

for (@reject) {
  print +(/$pattern/ ? "FAIL" : "PASS"), ": $_\n";
}
  (?!<foo)\s*bar

Bu boşluk maç olacak

php:

!preg_match(/foo\s*bar/,$string) && preg_match(/bar/,$string)

perl:

$string !~ /foo\s*bar/ && $string =~ /bar/

, Önceki cevapları dan bilgi alarak bir perl tek-liner gibi sarma ve düzenli ifadeler harf duyarsız yapma.

Pencereler:

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 içeren:

foo is bar
hello bar
foobar
foo     bar
barbar
bar foo
barfoo
foo foo

Bir komut isteminde bir-liner yürütme sonucu:

foo is bar
hello bar
barbar
bar foo
barfoo