2016-08-04 12 views
1

Ich habe eine Python-Datei alsParsing Python-Datei mit Re

test.py 

import os 
class test(): 

    def __init__(self): 
     pass 

    def add(num1, num2): 
     return num1+num2 

ich in einem String diese Datei lese wie:

with open('test.py', 'r') as myfile: 
    data=myfile.read() 

print data 

Nun, meine Daten enthalten die Zeichenfolge mit allen Linien und neuen Linien. Ich muss Linien mit Beginn der Klasse und def finden.

zum Beispiel:

Ich brauche die Ausgabe als gedruckt werden:

class test(): 
def __init__(self): 
def add(num1, num2): 

Wie kann ich diese mit regulären Ausdrücken zu verarbeiten?

+0

Was Sie 'process' bedeuten sie? –

+0

Ich muss die Zeichenfolge Daten verarbeiten, um die Ausgabe wie gezeigt – sam

+0

@ GáborErdős Ich glaube, er meint Regex. OP: Was ist deine Motivation? –

Antwort

2

zu verwenden Wenn Sie einen regulären Ausdruck Ansatz verfolgen möchten, verwenden Sie

re.findall(r'(?m)^[ \t]*((?:class|def)[ \t].*)', data) 

oder

re.findall(r'^[ \t]*((?:class|def)[ \t].*)', data, flags=re.M) 

Siehe regex demo

Der Punkt ist, dass Sieverwenden solltenals Beginn der Linie Anker (daher (?m) am Anfang oder re.M Flagge sind notwendig), dann passen Sie horizontal Whitespaces (mit [ \t]), dann entweder class oder def (mit (?:class|def)) und dann wieder einen Raum oder Tab und dann 0+ Zeichen außer einem Zeilenumbruch (.*). Wenn Sie auch Unicode-Leerzeichen verarbeiten möchten, müssen Sie [ \t] durch [^\S\r\n\f\v] ersetzen (und das Flag re.UNICODE verwenden).

Python demo:

import re 
p = re.compile(r'^[ \t]*((?:class|def)[ \t].*)', re.MULTILINE) 
s = "test.py \n\nimport os\nclass test():\n\n def __init__(self):\n  pass\n\n def add(num1, num2):\n  return num1+num2" 
print(p.findall(s)) 
# => ['class test():', 'def __init__(self):', 'def add(num1, num2):'] 
+0

Kannst du nicht' \ s' für die Whitespaces verwenden? –

+0

Nein, '\ s' stimmt mit einer neuen Zeile überein, aber' data' ist die gesamte Datei, die auch Zeilenumbrüche enthält. Vielleicht ist es in Ordnung, aber ich habe nicht mehr Eingabedaten, um es zu testen. –

+0

Nun, ich denke, Sie könnten '\ s +?' Für nicht-gieriges Match und '^ ... $' verwenden, um es auf eine Zeile zu beschränken. –

2

So, wenn Sie alle def und class Zeilen finden müssen, ist es viel einfacher, Regex zu vermeiden. genau dort

lesen Sie den ganzen Inhalt der hier Datei

with open('test.py', 'r') as myfile: 
    data=myfile.read() 

print data 

Warum Sie nicht nur die Antwort finden?

with open('test.py', 'r') as myfile: 
    for line in myfile: 
     stripped = line.strip() # get rid of spaces left and right 
     if stripped.startswith('def') or stripped.startswith('class'): 
      print(line) 

mit einer ganzen Reihe arbeiten, wie Sie angefordert:

import re 
with open('test.py', 'r') as myfile: 
    data = myfile.read() 

print(data) 

print(re.findall("class.+\n|def.+\n",data)) 

Wie Sie aus den Kommentaren sehen kann dies ‚als auch‘ als Bla Bla definiertem‘werden lassen. So ist es besser

print(re.findall("class .+\n|def .+\n",data)) 
+0

Dies funktioniert nicht mit den vorgesehenen Zeilen. –

+0

Ich möchte Zeile für Zeile nicht suchen. Meine Absicht ist, innerhalb einer vollständigen Reihe von Dateien zu suchen. – sam

+0

Ich korrigierte, um mit eingerückten Zeilen zu arbeiten –

1
with open('test.py', 'r') as myfile: 
    data=myfile.read().split('\n') 
    for line in data: 
     if re.search("(\s+)?class ", line) or re.search("^\s+def ", line): 
      print line