Qual é o equivalente python do grep -v?

14

Eu gosto grep -v . Eu uso isso o tempo todo. Mas também estou processando texto em python e há uma coisa crucial que me falta.

Geralmente eu uso grep -v para tirar coisas estranhas do texto.

Por exemplo,

$ grep -v '[a-z]'
# (I manually review this output to confirm that I don't want those lines)

$ grep '[a-z]' > linesiwanted

Mas como faço para corresponder ao complemento de uma regex em Python? Por exemplo, o complemento de \w?

ixtmixilix
fonte
Há uma discussão semelhante sobre grep em python no SO: stackoverflow.com/questions/1921894/grep-and-python , esta pergunta versão mais específica do que
icc97
\ w = qualquer palavra char \ W = qualquer palavra não char
Kasapo

Respostas:

17

Um regex em Python, quer a searchou matchmétodos, os retornos um Matchobjecto ou None. Para grep -vequivalente, você pode usar:

import re
for line in sys.stdin:
    if re.search(r'[a-z]', line) is None:
        sys.stdout.write(line)

Ou, mais concisamente:

import re; sys.stdout.writelines([line for line in sys.stdin if re.search(r'[a-z]', line) is None])
Arcege
fonte
+1 no link SO do comentário menciona afirmações negativas, mas para ser sincero, acho que seu snippet é muito mais sensível e elegante. obrigado.
Ixtmixilix
verifica-se que você também pode usar [^ az] para coincidir com o complemento do conjunto [az]
ixtmixilix
1

Acontece que você pode usar [^ az] para significar grep -v [a-z].

Estou usando como:

#!/usr/bin/env python
# coding=UTF-8

import sys, re

for file in sys.argv[1:]:
    f = open(file)
    string = f.read()
    regex = re.compile('[^a-z]')
    subs = regex.sub('', string)
    f.close()
    print subs
ixtmixilix
fonte
Estes não são os mesmos. grep -v '[a-z]'significa "excluir qualquer linha que contenha um caractere no intervalo de aaté z", mas você implementou o grep '[^a-z]'que significa "incluir qualquer linha que contenha um caractere que não esteja no intervalo de aaté z". Se uma linha tiver abc123, sua consulta a imprimirá erroneamente porque 1atende a esse critério. grep -v '[a-z]'não imprimirá esta linha porque asatisfaz os critérios negados.
Adam Katz