Perl Regex для исключения определенных строк в середине строки - PullRequest
1 голос
/ 14 июня 2019

У меня есть эта строка:

The file FILENAME has not been received

Я пытаюсь получить регулярное выражение, чтобы соответствовать этому, но не, если строка это (например):

The file FAILNAME has not been received

У меня пока есть это регулярное выражение:

/^(?=.*?\bThe\sfile\b)((?!FAILNAME).)*$/

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

Надеюсь, я объяснил это правильно:)

Заранее спасибо!

Ответы [ 3 ]

3 голосов
/ 14 июня 2019

Я бы сделал это в два шага:

if ($message =~ /\AThe file (\S+) has not been received\z/ && $1 ne 'FAILNAME') {

Т.е. используйте регулярное выражение для проверки общего формата и извлечения имени файла, а затем проверяйте извлеченное имя отдельно.

Зачем подставлятьвсе в одном регулярном выражении?

Кстати, вы можете втиснуть произвольные условия в регулярное выражение.Я не рекомендовал бы это в этом случае, но:

/\AThe file (\S+) has not been received\z(?(?{ $1 eq 'FAILNAME' })(*FAIL))/

Этот расширенный образец по существу говорит: «если $1 равно FAILNAME, не соответствует».

2 голосов
/ 14 июня 2019

Вы можете переместить отрицательный взгляд вперед после file, за которым следует символ пробела, чтобы утверждать, что прямо справа не является FAILNAME:

^The\sfile\s(?!\bFAILNAME\b).*$

Или этого не может произойти встрока после The file использует квантификатор:

^The\sfile\s(?!.*\bFAILNAME\b).*$

Если до и после FAILNAME ничего не может быть, вы можете посмотреть обходные пути:

^The\sfile\s(?!.*(?<!\S)FAILNAME(?!\S)).*$

Regex demo

0 голосов
/ 14 июня 2019

Я предполагаю, что мы хотим потерпеть неудачу с теми, которые имеют FAILNAME, с которым ваше оригинальное выражение работает нормально, и затем мы немного изменим это, что может сработать:

^(?=The\sfile\s)(?!.*\s\bFAILNAME\b\s.*).*$

Демо 1

Здесь мы добавляем два пробела в качестве дополнительных левой и правой границ, которые, если мы не хотим их иметь, мы бы просто исключили.

Пример

use strict;

my $str = 'The file FILENAME has not been received
The file FILENAME has been received
The file FILENAME
The file AFAILNAME has not been received
FILENAME
The file FAILNAME has not been received
FAILNAME has not been received
The file FAILNAME


';
my $regex = qr/^(?=The\sfile\s)(?!.*\s\bFAILNAME\b\s.*).*$/mp;

if ( $str =~ /$regex/g ) {
  print "Whole match is ${^MATCH} and its start/end positions can be obtained via \$-[0] and \$+[0]\n";
  # print "Capture Group 1 is $1 and its start/end positions can be obtained via \$-[1] and \$+[1]\n";
  # print "Capture Group 2 is $2 ... and so on\n";
}

# ${^POSTMATCH} and ${^PREMATCH} are also available with the use of '/p'
# Named capture groups can be called via $+{name}

RegEx Circuit

jex.im визуализирует регулярные выражения:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...