2009-08-20 7 views
4

Я довольно новичок в регулярных выражениях и нуждаюсь в некоторой помощи. Мне нужно отфильтровать некоторые строки, используя регулярное выражение в Perl. Я собираюсь передать регулярное выражение в другую функцию, поэтому это нужно сделать в одной строке.Как я могу комбинировать положительное и отрицательное состояние в регулярном выражении?

Я хочу, чтобы выбрать только те строки, которые содержат "too long" и которые не начинаются с "SKIPPING"

Вот мои тестовые строки:

Пропустив эту связь, поскольку погашения слишком долго
TKIPPING этой связи, поскольку срок погашения слишком длинный
УДАЛЕНИЕ этой облигации со сроком погашения слишком долго
Здравствуйте, этот срок погашения слишком длинный
это слишком длинное
привет

правило регулярное выражение должно соответствовать следующим на «слишком долго":

Пропустив эту связь, поскольку погашения слишком долго
хлопая эту связь, поскольку зрелости слишком долго
Привет это зрелость слишком долго
это слишком долго

и он должен пропустить:

«привет», потому что он не содержит «слишком долго»
«Пропустив эту связь с момента погашения слишком долго», потому что containst «» Пропустив

ответ

11
/^(?!SKIPPING).*too long/ 
+0

Очень круто. Благодарю. У меня есть способы научиться регулярному выражению! – autodidact

+0

ЭТО, как негативный внешний вид сделан в Perl. Нет знака '<'. –

+4

Собственно, это негативный взгляд. Отрицательный lookbehind действительно имеет '<' ... синтаксис '(? chaos

-2

Использование отрицательного просмотра назад:

(?<!^SKIPPING)too long$ 
+0

Не работает. Попробуй. – chaos

+0

Я не уверен в синтаксисе?

+0

Вы не можете использовать переменную длину lookbehind. – Axeman

10

Лично я сделал бы это как два отдельных регулярных выражения, чтобы сделать их более ясными.

while (<FILE>) 
{ 
    next if /^SKIPPING/; 
    next if !/too long/; 

    ... do stuff 
} 
+0

-1 в не ответе. –

+9

Что значит «Не ответ»? Он выполняет именно то, что хочет, просто не так, как он думал, чтобы это сделать. Для меня это ответ. –

1

Использовать lookahead; см. this explanation of regex lookaround.

^(?!SKIPPING).*too long 
+0

Этот сайт, очевидно, неверен в отношении синтаксиса для негативного внешнего вида, к сожалению. –

+0

@ Даниэль: нет, это не так. Я думаю, вы здесь смущены. – ysth

+0

@ Daniel: Как сайт ошибается? Отрицательный lookbehind принимает форму '(?

3

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

use strict; 
use warnings; 

for my $line (<DATA>) { 
    next if $line =~ m/^SKIPPING/; 
    next if $line !~ m/too long/; 

    # do something with $line 
    chomp $line; 
    say "Found: ", $line, ':length=', length($line); 
} 

__DATA__ 
SKIPPING this bond since maturity too long 
TKIPPING this bond since maturity too long 
SLAPPING this bond since maturity too long 
Hello this maturity too long 
this is too long 
hello there 
-1
/^(?<!SKIPPING).*too long$/ 

Матчи линии, которые вы ищете. Знак доллара в конце приводит к тому, что он соответствует только строкам, заканчивающимся «слишком длинным».

Надеюсь, это поможет!