regex, улавя условно ред, който не съдържа подниз

моят код анализира някои редове в лог файл.

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

разбирам доста добре регулярните изрази. но не мога да разбера това.

проблемът: искам да заснема всеки ред, който не съдържа думата error или warn. освен ако не е първата част от записа в журнала и е ограден с квадратни скоби.

досега опитах нещо подобно:

(((?:abc|cba)\s+.*(?!\[?(?!error|warn)\]?).*)|((abc|cba)\s+\[(error|warn)\]\s+(.*)))

редовете в дневника могат да изглеждат като някои от тези примери:

група за улавяне 2:

abc [error] message
cba [error] message
cba [warn] message

група за улавяне 1:

abc something random
cba i dont know

не заснемане:

abc some [error] message
cba some [warn] message

проблемът на по-прост английски; Искам да получа всеки ред, който започва с abc или cba. група за улавяне 1 трябва да вземе реда, ако няма [error] или [warn] никъде в него. и група за улавяне 2 трябва да го получи само ако [error] или [warn] са първата част от записа (след abc или cba)


person Inbar Rose    schedule 09.10.2012    source източник
comment
Така че регулярният израз трябва да работи само в 1 ред? Като предавате редове един по един към регулярния израз за проверка?   -  person nhahtdh    schedule 09.10.2012
comment
@nhahtdh всеки ред от файла се анализира от регулярния израз. 1 по 1. да.   -  person Inbar Rose    schedule 09.10.2012


Отговори (1)


Това трябва да свърши работа:

^(?:abc|cba)(?:(?!.*(?:\[error\]|\[warn\]))|\s*(?:\[error\]|\[warn\])).*$

Обърнете внимание, че твърдя, че целият ред съответства на регулярния израз с ^ и $.

Първо проверявам за abc и cba, които започват линията.

След това 2 случая:

  • Нито [error], нито [warn] се появяват никъде в реда: (?!.*(?:\[error\]|\[warn\])) (?: не е много важен, просто група без прихващане).
  • Или [error] или [warn] следват веднага след abc и cba: \s*(?:\[error\]|\[warn\]). Имайте предвид, че може да искате да промените \s* на \s+, тъй като текущият регулярен израз ще съответства на abc[error].

Тогава останалото не ме интересува .*, но трябва да е там, тъй като използвах $. Не съм напълно сигурен за Python: проверете дали можете да премахнете .*$ част от регулярния израз.

Правя всички групи незахващащи, тъй като изглежда, че твърдите, че редът следва определен формат. Ако трябва да извлечете някои данни от линията едновременно, уведомете ме.

person nhahtdh    schedule 09.10.2012
comment
много благодаря. вашето решение ми помогна да намеря това, което работи за моето. ако се интересувам, в момента използвам: ((?:abc|cba)(?!.*(?:\[(?:error|warn)\]).*).*)|((abc|cba)\s+\[(error|warn)\]\s+(.*)) - нещото, което го накара да работи, беше включването на .* в отрицателния поглед напред ((?!)) :) regexr.com?32db0 - person Inbar Rose; 09.10.2012
comment
@InbarRose: Не съм сигурен коя функция използвате, но проверете този случай: "sfdkjsfhk abc [error] askdjhaksd" - трябва да се отхвърли. - person nhahtdh; 09.10.2012
comment
да - знам, но това е само част от основния регулярен израз. което се отнася за различни неща. благодаря за загрижеността. просто се опитвах да разбера конкретно как да игнорирам редове с този конкретен формат след цялата останала работа. - също така - свързах грешен регулярен израз - трябва да е regexr.com?32db3 - person Inbar Rose; 09.10.2012