2013-10-10 2 views
0

Я использую perl для синтаксического анализа большого файла отчета. Я вытаскиваю имена, ища фамилию и имя в начале некоторых строк отчета. Я пытаюсь исключить текст после имени. Некоторые из этих текстовых полей являются числами, поэтому легко - я просто ищу несимметричные символы. Но некоторые из них являются фиксированными текстовыми полями, которые я могу перечислить.Как исключить определенный текст в perl regexp match

E.g. ---

LastNameA, FirstNameA 
LastNameB, FirstNameB 345C 
LastNameC, FirstNameC BADTEXT 
LastNameD, FirstNameD MOREBADTEXT 

Я попытался следующие

/^(\D*)((BADTEXT|MOREBADTEXT|))/ 
/^(\D*)(BADTEXT|MOREBADTEXT|)/ 
/^(\D*?)((BADTEXT|MOREBADTEXT|))/ 
/^(\D*)((BADTEXT|MOREBADTEXT)?)/ 
/^(\D*)(?:(BADTEXT|MOREBADTEXT|))/ 

и несколько других комбинаций. Но я не получаю ни матч, ни матч с BADTEXT или MOREBADTEXT, втянутыми в $ 1 вместо $ 2. Я либо хочу, чтобы плохой текст в $ 2, или совсем не совпал.

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

Я прочитал perlretut дважды, но не могу найти, как это сделать. Похоже, это должно быть просто! Буду признателен за любую оказанную помощь.

+0

Просто игнорируйте дополнительный текст, который вы не хотите в своем регулярном выражении: '/ (\ w +), (\ w +) /'? –

+0

Спасибо за комментарий, но это не работает, потому что поле имени иногда имеет средний начальный, JR, SR и т. Д. – lp1756

ответ

1

Как насчет разделения текста на пробелы и сохранения только тех частей, которые вам нравятся?

#!/usr/bin/perl 

use strict; 
use warnings; 

while (my $line=<DATA>) { 
    my @name=grep { ! /\d|^BADTEXT$|^MOREBADTEXT$/ } split /\s+/, $line; 
    print "@name\n"; 
} 

__DATA__ 
LastNameA, FirstNameA 
LastNameB, FirstNameB 345C 
LastNameC, FirstNameC BADTEXT 
LastNameD, FirstNameD MOREBADTEXT 

Результат:

LastNameA, FirstNameA 
LastNameB, FirstNameB 
LastNameC, FirstNameC 
LastNameD, FirstNameD 

Это, конечно, означает, что вы должны знать, что имена не имеют цифры в них (не Уэйнрайт 3, LOUDON), и что вы можете создать исчерпывающий список текстов вы хотите исключить, и что они никогда не равны словам в именах.

Если вы знаете, что существует только одно последнее имя и одно имя, вы можете просто захватить первые два элемента, которые split() возвращает.

+0

Это будет работать. Я упрямо искал решение, которое вложило все в одно регулярное выражение. Но иногда лучше держать его простым и двигаться дальше! Благодарю. – lp1756

+0

Обычно регулярные выражения хотят делать все. Иногда это только усложняет ситуацию. – asjo

Смежные вопросы