web-dev-qa-db-fra.com

correspondance de modèle 'négative' en python

J'ai l'entrée suivante

OK SYS 10 LEN 20 12 43
1233a.fdads.txt,23 /data/a11134/a.txt
3232b.ddsss.txt,32 /data/d13f11/b.txt
3452d.dsasa.txt,1234 /data/c13af4/f.txt
.

Et j'aimerais extraire toutes les entrées sauf la ligne contenant "OK SYS 10 LEN 20" et la dernière ligne contenant un seul "." (point) . 

1233a.fdads.txt,23 /data/a11134/a.txt
3232b.ddsss.txt,32 /data/d13f11/b.txt
3452d.dsasa.txt.1234 /data/c13af4/f.txt

J'ai essayé le suivant,

for item in output:
    matchObj = re.search("^(?!OK) | ^(?!\\.)", item)
    if matchObj:
        print "got item "  + item

mais cela ne fonctionne pas, car il ne produit aucun résultat. 

15
JosiP

Voir en action :

matchObj = re.search("^(?!OK|\\.).*", item)

N'oubliez pas de mettre .* après le négatif, sinon vous ne pourriez pas obtenir de correspondance ;-)

35
mmdemirbas
 if not (line.startswith("OK ") or line.strip() == "."):
     print line
4
Jochen Ritzel

Utilisez une correspondance négative. (Notez également que les espaces sont significatifs, par défaut, dans une expression rationnelle, évitez donc d'espacer les choses. Vous pouvez également utiliser re.VERBOSE .)

for item in output:
    matchObj = re.search("^(OK|\\.)", item)
    if not matchObj:
        print "got item " + item
4
Marcelo Cantos

Pourquoi ne faites-vous pas correspondre à la ligne OK SYS et ne le retournez pas.

for item in output:
    matchObj = re.search("(OK SYS|\\.).*", item)
    if not matchObj:
        print "got item "  + item
2
Pablo Jomer

S'il s'agit d'un fichier, vous pouvez simplement ignorer les première et dernière lignes et lire le reste avec csv:

>>> s = """OK SYS 10 LEN 20 12 43
... 1233a.fdads.txt,23 /data/a11134/a.txt
... 3232b.ddsss.txt,32 /data/d13f11/b.txt
... 3452d.dsasa.txt,1234 /data/c13af4/f.txt
... ."""
>>> stream = StringIO.StringIO(s)
>>> rows = [row for row in csv.reader(stream,delimiter=',') if len(row) == 2]
>>> rows
[['1233a.fdads.txt', '23 /data/a11134/a.txt'], ['3232b.ddsss.txt', '32 /data/d13f11/b.txt'], ['3452d.dsasa.txt', '1234 /data/c13af4/f.txt']]

Si c'est un fichier, alors vous pouvez faire ceci:

with open('myfile.txt','r') as f:
   rows = [row for row in csv.reader(f,delimiter=',') if len(row) == 2]
1
Burhan Khalid
and(re.search("bla_bla_pattern", str_item, re.IGNORECASE) == None)

travaille.

0
hkn06tr

Vous pouvez également le faire sans regarder en avant. Vous devez simplement ajouter des parenthèses à la partie de l'expression que vous souhaitez extraire. Cette construction avec des parenthèses s'appelle group.

Ecrivons le code python:

string = """OK SYS 10 LEN 20 12 43
1233a.fdads.txt,23 /data/a11134/a.txt
3232b.ddsss.txt,32 /data/d13f11/b.txt
3452d.dsasa.txt,1234 /data/c13af4/f.txt
.
"""

search_result = re.search(r"^OK.*\n((.|\s)*).", string)

if search_result:
    print(search_result.group(1))

La sortie est:

1233a.fdads.txt,23 /data/a11134/a.txt
3232b.ddsss.txt,32 /data/d13f11/b.txt
3452d.dsasa.txt,1234 /data/c13af4/f.txt

^OK.*\n trouvera la première ligne avec l'instruction OK, mais nous ne souhaitons pas l'extraire, laissez-la sans parenthèses. Ensuite, nous voulons capturer une partie: ((.|\s)*), mettez-la donc entre parenthèses. Et à la fin de l'expression rationnelle, nous recherchons un point ., mais nous ne voulons pas non plus le capturer.

P.S: Je trouve cette réponse très utile pour comprendre le pouvoir des groupes. https://stackoverflow.com/a/3513858/4333811

0
Alex Misulya