2016-05-06 16 views
0

Ich versuche, das folgende mit einem Python Regex zu analysieren.Wie erstellt man mehrzeilige Python-Regex zum Parsen gehen Importe

import (
    "github.com/user/qrt" 

    "fmt" 

    "github.com/user/zyx" 
) 

import "abcdef" 

import "abzdef" 

Idealfall eine einzelne Regex ergäbe:

alles innerhalb der Pars als eine einzige Gruppe und jedes Element in den einzelnen Zeile Import-Anweisungen als Gruppe

Hier ist, was ich für jede Import-Anweisung habe separat. (Siehe Bit rechts von Kolon ..

# import (...) : r'import\s*(\()(.*?)(\))' 
# import ".." : r'import\s*(\")(.*?)(\")' 

Ich denke ich so etwas wie unten verwenden könnte gegen die erste Gruppe passen Entscheidung zu behandeln, wenn ich das Parsen ein() Imports oder einen „“ Import. ((id) ja |? nein)? Spiel 'ja', wenn Gruppe 'id' angepasst, sonst 'nein'

Antwort

1

So etwas

Ideone.com

import re 

test = """import (
    "github.com/user/qrt" 

    "fmt" 

    "github.com/user/zyx" 
) 

import "abcdef" 

import "abzdef" 
""" 

rx = re.compile(r'import\s+([^(]+?$|\([^)]+\))', re.MULTILINE) 
rx2 = re.compile(r'".*"', re.MULTILINE) 

for m in rx.finditer(test): 
    imp = m.group(1) 
    if imp[0] == '(': 
     for m in rx2.finditer(imp): 
      print(m.group(0)) 
    else: 
     print(m.group(1)) 

Ouput

"github.com/user/qrt" 
"fmt" 
"github.com/user/zyx" 
"abcdef" 
"abzdef" 

EDIT Just for fun habe ich versucht, ein Mockup Rekursiver Abstieg. Es erlaubt gebrochene Syntax; aber es ist eine Idee und ist einfach zu bedienen, nur iterieren.

http://ideone.com/iS4aww

import re 

test = """import (
    "github.com/user/qrt" 

    "fmt" 

    "github.com/user/zyx" 
) 

import "abcdef" 

import "abzdef" 
""" 

BEGIN = 1 
IMPORT = 2 
DESCENT = 3 


class Lexer(object): 
    def __init__(self, text): 
     self._rx = re.compile(r'(import|".*?"|\(|\))') 
     self._text = text 

    def __iter__(self): 
     for m in self._rx.finditer(self._text): 
      yield m.group(1) 


class RecursiveDescent(object): 
    state = BEGIN 

    def __init__(self, lexer): 
     self._lexer = lexer 

    def __iter__(self): 
     for token in self._lexer: 
      if self.state == BEGIN: 
       if token != 'import': 
        # Beginning of the program most likely 
        raise StopIteration 
       self.state = IMPORT 
      elif self.state == IMPORT: 
       if token == '(': 
        self.state = DESCENT 
       else: 
        self.state = BEGIN 
        yield token 
      elif self.state == DESCENT: 
       if token == ')': 
        self.state = BEGIN 
       else: 
        yield token 

for path in RecursiveDescent(Lexer(test)): 
    print(path) 

Ausgabe

"github.com/user/qrt" 
"fmt" 
"github.com/user/zyx" 
"abcdef" 
"abzdef" 
+0

Ich mag diese, wurde aber für eine einzelne Regex der Hoffnung, wenn es möglich ist. – bdbaddog

+0

Es ist nicht möglich mit Regex. Sie benötigen einen http://en.wikipedia.org/wiki/Recursive_descent_parser, welcher Art es ist. Überprüfen Sie http://stackoverflow.com/questions/5060659/python-regexes-how-to-access-multiple-matches-of-a-group. – totoro

+0

@bdbaddog Hat einen verrückten Schnitt gemacht :-) – totoro