Was ist das Python-Äquivalent von grep -v?

13

Ich mag grep -v. Ich benutze es die ganze Zeit. Aber ich mache auch eine Textverarbeitung in Python, und es gibt eine entscheidende Sache, die mir fehlt.

Normalerweise entferne ich grep -vfremde Dinge aus dem Text.

Zum Beispiel,

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

$ grep '[a-z]' > linesiwanted

Aber wie passe ich das Komplement eines Regex in Python an? Zum Beispiel die Ergänzung von \w?

ixtmixilix
quelle
Es gibt eine ähnliche Diskussion über grep in python auf SO: stackoverflow.com/questions/1921894/grep-and-python , diese Frage spezifischere Version davon
icc97
\ w = ein beliebiges Wortzeichen \ w = ein beliebiges Nicht-Wortzeichen
Kasapo

Antworten:

17

Ein regulärer Ausdruck in Python, entweder die Methode searchoder match, gibt ein MatchObjekt oder zurück None. Für eine grep -vEntsprechung könnten Sie Folgendes verwenden:

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

Oder genauer:

import re; sys.stdout.writelines([line for line in sys.stdin if re.search(r'[a-z]', line) is None])
Arcege
quelle
+1 der SO-Link im Kommentar erwähnt negative Lookahead-Behauptungen, aber um ehrlich zu sein, finde ich Ihr Snippet viel vernünftiger und eleganter. Vielen Dank.
ixtmixilix
es stellt sich heraus, dass Sie auch [^ az] verwenden können, um das Komplement der Menge [az]
ixtmixilix 24.02.12
1

Es stellt sich heraus, dass Sie mit [^ az] nur meinen können grep -v [a-z].

Ich benutze es wie folgt:

#!/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
quelle
Das ist nicht dasselbe. grep -v '[a-z]'bedeutet "alle Zeilen ausschließen, die ein Zeichen im Bereich von abis enthalten z", aber Sie haben implementiertgrep '[^a-z]' was bedeutet "eine Zeile einschließen, die ein Zeichen enthält, das nicht im Bereich von abis liegt z". Wenn eine Zeile vorhanden ist, abc123wird sie von Ihrer Abfrage fälschlicherweise gedruckt, da 1diese Kriterien erfüllt sind. grep -v '[a-z]'Diese Zeile wird nicht gedruckt, da adie negierten Kriterien erfüllt sind.
Adam Katz