web-dev-qa-db-fra.com

re.search Python à plusieurs lignes

re.search avec\s ou '\ n' ne trouve pas le multiligne que je cherche. 

Portion de source:

Date/Time:
2013-08-27 17:05:36 

----- BEGIN SEARCH -----

GENERAL DATA:
NAME:   AB12
SECTOR: 
999,999
CONTROLLED BY:  Player
ALLIANCE:   Aliance
ONLINE: 1 seconds ago
SIZE:   Large
HOMEWORLD:  NO
APPROVAL RATING:    100%
PRODUCTION RATE:    100%

RESOURCE DATA:
POWER:  0 / 0
BUILDINGS:  0 / 20
ORE:    80,000 / 80,000
CRYSTAL:    80,000 / 80,000
POPULATION: 40,000 / 40,000

BUILDING DATA:
N/A

UNIT DATA:
WYVERN(S):  100

----- END SEARCH -----

En le regardant dans Notepad ++, je vois "BUILDING DATA: (LF)" 

Code complet

lines = open('scan.txt','r').readlines()
for a in lines:
    if re.search(r"\A\d", a):
        digits = a
        if re.search(r"2013", digits):
            date.append(digits[:19])
            count +=1
        Elif re.search(r",", digits):
            clean = digits.rstrip()
            sector = clean.split(',')
            x.append(sector[0])
            y.append(sector[1])
    Elif re.search(r"CONTROLLED BY:", a):
        player.append(a[15:].rstrip())
    Elif re.search(r"ALLIANCE:", a):
        alliance.append(a[10:].rstrip())
    Elif re.search(r"SIZE:", a):
        size.append(a[6:].rstrip())
    Elif re.findall('BUILDING DATA:\sN/A', a, re.M):
        def_grid = ''
        print "Didn't find it"
        defense.append(def_grid)
        defense_count +=1
    Elif re.search(r"DEFENSE GRID", a):
        def_grid = a[16:].rstrip()
        print "defense found"
        defense_count +=1

Mais je ne reçois rien.

J'ai besoin de mettre un espace vide lorsque "DEFENSE GRID" n'existe pas après "BUILDING DATA:"

Je sais qu'il me manque quelque chose et j'ai essayé de lire plus de recherches, mais je ne suis pas en mesure de trouver des exemples détaillés qui expliquent le fonctionnement du multiligne.

10
Xariec
re.findall("BUILDING DATA:\nN/A",a,re.MULTILINE)
8
Goontracker

Vous pouvez faire exactement ce que vous avez fait, mais en utilisant re.findall au lieu de re.search:

re.findall('BUILDING DATA:\nN/A', a, re.M)
#['BUILDING DATA:\nN/A']

MODIFIER:

Le problème est que vous lisez actuellement ligne par ligne. Pour détecter un motif appartenant à deux lignes ou plus, vous devez considérer la chaîne dans son ensemble, peut-être en effectuant:

s = ''.join(lines)

ce qui est correct si lines n'est pas si gros, puis utilisez s pour effectuer vos recherches multiligne ...

5
Saullo G. P. Castro

Je me demande pourquoi tu n'as rien rendu. Si votre fichier ressemble à ceci:

BUILDING DATA:
N/A

Je me sers 

import re
f = open('test.txt','r')
a = f.read(20)
re.search('BUILDING DATA:\nN/A', a, re.M)

une sortie. C'est

<_sre.SRE_Match object at 0x1004fc8b8>

Si je teste re.search avec une chaîne, ce n'est pas dans le fichier comme dans ce code:

import re
f = open('test.txt','r')
a = f.read(20)
re.search('BUILDING BATA:\nN/A', a, re.M)

il n'y a pas de sortie comme prévu.

MODIFIER:

Comme Saullo Castro l'a souligné, le problème est la lecture ligne par ligne. Pourquoi ne pas utiliser quelque chose comme ça? 

a = open('scan.txt','r').read()
if re.findall('BUILDING DATA:\nN/A', a, re.M):
     print('found!')

3ème essai:

tmp = False
...
Elif re.findall('BUILDING DATA:', a, re.M):
    tmp = True
Elif tmp and re.findall('N/A', a, re.M):
    def_grid = ''
    print "Didn't find it"
    defense.append(def_grid)
    defense_count +=1
1
Stefan Bollmann

Remplacer

re.findall('BUILDING DATA:\sN/A', a, re.M):

avec

re.findall('BUILDING DATA:\nN/A', a, re.M):

ou

re.search(r'BUILDING DATA:\nN/A', a, re.M):

et ça devrait marcher.

(Notez que dans votre code, il y a \s au lieu de \n)

0
sharhp