2012-08-08 22 views
15

Ben büyük metin var alt dize olmadan dize bulmak:Düzenli ifadeler:

"Big piece of text. This sentence includes 'regexp' word. And this 
sentence doesn't include that word" 

Ben 'bu' başlar ve 'kelimesi' tarafından biter alt dizeyi bulmalıyız amadeğil 'regexp' sözcüğünü dahil edin.

Bu durumda dize: "this sentence doesn't include that word" tam olarak almak istediğim şeydir.

Bunu, Normal İfadeler aracılığıyla nasıl yapabilirim?

+0

Kurallarınız kafa karıştırıcı veya beklenen çıktınızı aldığınız bir hata yaptınız. Neden "Ve" yok ve neden "Büyük metin parçası" yok? – sjakubowski

+0

@sjakubowski "substring 'this' ile başlar ve 'word' ile biter." – Mathletics

+0

Bu kurallar kafa karıştırıcı ancak doğrudur. Google'da bir şey bulmak için çok zaman harcadım ama hiçbir şey bulamadım. – Artem

cevap

27

bir durum görmezden seçeneği ile aşağıdaki çalışması gerekir:

\bthis\b(?:(?!\bregexp\b).)*?\bword\b 

Örnek: http://www.rubular.com/r/g6tYcOy8IT

Açıklama:

\bthis\b   # match the word 'this', \b is for word boundaries 
(?:    # start group, repeated zero or more times, as few as possible 
    (?!\bregexp\b) # fail if 'regexp' can be matched (negative lookahead) 
    .     # match any single character 
)*?    # end group 
\bword\b   # match 'word' 

\b her kelimeyi çevreleyen sen 'wordy' in 'devedikeni', ya da 'kelimesi' 'Bu' eşleştirme gibi altdizgelerin üzerinde uymayan emin olur.

Hariç tutulan sözcüğün oluşmadığından emin olmak için, başlangıç ​​kelimenizle bitiş kelimeniz arasındaki her karakterin kontrol edilmesiyle çalışır.

+2

Tam olarak ihtiyacım olan şey bu! Teşekkür ederim! Normal ifadenin ve onunla oynayabilecek bağlantının iyi açıklaması için – Artem

+2

+1 - bunu benzer bir şeye uygulayabiliyordum ve açıklama yapmadan mücadele edebiliyordum. Nasıl çalıştığını söylemeden biraz kod veren cevaplardan bıktım. –

+0

Bana çok yardımcı oldunuz! Teşekkürler! –

3

Lookahead assetions kullanın. Eğer bir dize başka alt dize içermiyor olmadığını kontrol etmek istediğinizde

yazabilirsiniz:

/^this(?!.*substring).*word$/ 
:

/^(?!.*substring)/ 

Ayrıca başlangıç ​​ve this ve word için yolun sonu kontrol etmeli

Burada başka bir sorun, dizeleri bulmamanız, cümle bulmak (eğer görevinizi doğru anlıyorsam).

Yani çözüm şuna benzer: kullanım

perl -e ' 
    local $/; 
    $_=<>; 
    while($_ =~ /(.*?[.])/g) { 
    $s=$1; 
    print $s if $s =~ /^this(?!.*substring).*word[.]$/ 
    };' 

Örnek:

$ cat 1.pl 
local $/; 
$_=<>; 
while($_ =~ /(.*?[.])/g) { 
    $s=$1; 
    print $s if $s =~ /^\s*this(?!.*regexp).*word[.]/i; 
}; 

$ cat 1.txt 
This sentence has the "regexp" word. This sentence doesn't have the word. This sentence does have the "regexp" word again. 

$ cat 1.txt | perl 1.pl 
This sentence doesn't have the word. 
+0

Bu tek bakış, işi yapmayacak; Yuvalanmış lookaheads kullanmanız gerekir. Ve takip eden kod snippet'i hiçbir açıklama olmadan okumak (Perl'i bilmiyorum) için oldukça zordur. :/ – KRyan

+0

@DragoonWraith: Sen neden bahsediyorsun? Bu soultiyon görevi çözüyor. Kendin deneyebilirsin. –

+0

Gönderilen RegEx'i denedim ve bunu yapmadı. '(?!' alt yazı dilinin 'bu'dan sonra (örnekte), alt-sözcük' 'kelimesinden sonra görünse bile, herhangi bir durumla eşleşmesini engeller. Yuvalanmış' '(? :(?!' her FJ ') s cevabı bunu düzeltir.Bu snippet'i test etmek için Perl'im yok, ama ona bakarak herhangi bir şey öğrenemiyorum ve bir dizge ile manüel olarak dolaştığı anlaşılan bir RegEx çözümü olduğunu söyleyemem. bu 'while' döngüsü. Soru 'regex' etiketli değil perl '. – KRyan

İlgili konular