2012-08-08 9 views
15

mam duży tekst:Wyrażenia regularne: znaleźć ciąg bez podciąg

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

Muszę znaleźć podciąg, który zaczyna się od „tym” i kończy „słowa” ale nie zawierają słowo "regexp".

W tym przypadku napis: „this sentence doesn't include that word” jest dokładnie to, co chcę otrzymywać.

Jak mogę to zrobić za pomocą wyrażeń regularnych?

+0

Twoje zasady są mylące lub popełniłeś błąd z oczekiwanym wynikiem. Dlaczego nie "I" i dlaczego nie "Duży kawałek tekstu". – sjakubowski

+0

@sjakubowski "podciąg zaczyna się od" this "i kończy się na" słowie "" – Mathletics

+0

Zasady te są mylące, ale poprawne. Spędziłem dużo czasu, aby znaleźć coś w Google, ale nic nie znalazłem. – Artem

Odpowiedz

27

Z zignorować sprawę opcji, następujące powinny działać:

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

Przykład: http://www.rubular.com/r/g6tYcOy8IT

Objaśnienie:

\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 otaczające każde słowo zapewnia, że ​​nie są dopasowane na podciągi, jak dopasowanie do „tego” w „oset”, lub „słowa” w „rozwlekły”.

ten działa poprzez sprawdzenie w każdej postaci między twego słowa początkowego i końcowego swoim słowem, aby upewnić się, że wyłączone słowo nie występuje.

+2

Dokładnie tego potrzebuję! Dziękuję Ci! – Artem

+2

+1 za dobre wyjaśnienie regex i link do zabawy - udało mi się zastosować to do czegoś podobnego i walczyłbym bez wyjaśnienia. Mam dość odpowiedzi, które dają trochę kodu, nie mówiąc, jak to działa. –

+0

Bardzo mi pomogłeś! Dzięki! –

3

Skorzystaj z asynchronizacji z wyprzedzeniem.

Jeśli chcesz sprawdzić, czy łańcuch nie zawiera innego podciąg, można napisać:

/^(?!.*substring)/ 

Należy sprawdzić również początek i koniec linii dla this i word:

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

Innym problemem jest to, że nie pracujesz nad szukaniem ciągów, chcesz znaleźć zdania (jeśli dobrze rozumiem twoje zadanie).

więc rozwiązanie wygląda tak:

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

Przykład użycia:

$ 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

Samo uprzedzenie nie wykona zadania; musisz użyć zagnieżdżonych przodków. Fragment kodu, który następuje, jest raczej trudny do odczytania (nie znam Perla) bez żadnego wyjaśnienia. :/ – KRyan

+0

@DragoonWraith: o czym ty mówisz? Ta dusza rozwiązuje zadanie. Możesz spróbować sam. –

+0

Wypróbowałem RegEx opublikowany i nie zrobił tego. '(?!' uniemożliwi mu dopasowanie dowolnego przypadku, w którym podła pojawi się po 'this' (z przykładu), nawet jeśli podła pojawi się po' słowie' .Za pomocą zagnieżdżonego '(? :(?!' na FJ ' s odpowiedź naprawia to.Nie mam Perla do przetestowania tego fragmentu, ale niczego się nie uczę, patrząc na niego, i z tego co mogę * powiedzieć, że to nie jest rozwiązanie RegEx, ponieważ wydaje się, że ręcznie przechodzę przez ciąg z ta pętla 'while'. Pytanie oznaczone tagiem 'regex', a nie' perl'. – KRyan

Powiązane problemy