Регулярные выражения: найти строку без подстроки

У меня есть большой текст:

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

Мне нужно найти подстроку, начинающуюся с this и заканчивающуюся словами > , но не включает слово > регулярное выражение.

В этом случае строка: "this sentence doesn't include that word" именно то, что я хочу получить.

Как это сделать с помощью регулярных выражений?

Ответы

Ответ 1

С опцией "игнорировать регистр" должно работать следующее:

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

Пример: http://www.rubular.com/r/g6tYcOy8IT

Пояснение:

\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, окружающее каждое слово, гарантирует, что вы не подходите под подстроки, например, сопоставляете 'this' в чертополохе или слово "слово".

Это работает, проверяя каждый символ между вашим стартовым словом и вашим конечным словом, чтобы убедиться, что исключенное слово не встречается.

Ответ 2

Использовать подсчеты.

Если вы хотите проверить, не содержит ли строка другой подстроки, вы можете написать:

/^(?!.*substring)/

Вы должны также проверить начало и конец строки для this и word:

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

Другая проблема заключается в том, что вы не работаете с поисковыми строками, вы хотите найти предложения (если я правильно понимаю вашу задачу).

Итак, решение выглядит так:

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

Пример использования:

$ 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.