2017-06-02 5 views
1

Ich versuche, eine hierarchische Struktur von Abschnitten, Unterabschnitten, Unterunterabschnitte in einer Wikipedia-Seite zu erhalten.Erhalten hierarchische Struktur von Python-String

Ich habe eine Zeichenfolge wie folgt:

mystr = 'a = b = = c = == d == == e == === f === === g === ==== h ==== === i === == j == == k == = l =' 

In diesem Fall wird der Seitenname ist ‚a‘ und die Struktur folgt

= b = 
= c = 
    == d == 
    == e == 
    === f === 
    === g === 
     ==== h ==== 
    === i === 
    == j == 
    == k == 
= l = 

Die Gleichheitszeichen Indikatoren Abschnitt oder Unter sind Abschnitt und so weiter. Ich brauche eine Python-Liste mit allen relationalen hierarchischen Strukturen wie folgt zu erhalten:

mylist = ['a', 'a/b', 'a/c', 'a/c/d', 'a/c/e', 'a/c/e/f', 'a/c/e/g', 
      'a/c/e/g/h', 'a/c/e/i', 'a/c/j', 'a/c/k', 'a/l'] 

Bisher habe ich in der Lage gewesen, indem Sie diese in den Abschnitten, Unterabschnitten und so weiter zu finden:

sections = re.findall(r' = (.*?)\ =', mystr) 
subsections = re.findall(r' == (.*?)\ ==', mystr) 
... 

Aber ich weiß nicht, wie ich von hier fortfahren soll, um die gewünschte Liste zu bekommen.

+1

Willkommen bei SO. Um Ihre Frage zu verbessern, beschreiben Sie bitte, wie die hierarchische Struktur aus der Zeichenkette (d. H. Die Bedeutung der Gleichheitszeichen) und der Postleitzahl, die zeigt, was Sie bereits versucht haben, bestimmt werden sollte. –

+0

Grundsätzlich versuche ich Text aus Wikipedia zu extrahieren. Die Zeichenfolge enthält die Inhaltsnamen einer bestimmten Wikipedia-Seite (Abschnitte, Unterabschnitte, Unterunterabschnitte usw.). In meinem Beispiel ist ein Seitenname; b, c, l sind Abschnitte (also haben sie nur ein Gleichheitszeichen); d, e, j sind Unterabschnitte unter c (also haben sie zwei gleiche Zeichen um sie herum) und so weiter. – user8101320

Antwort

0

Sie können es wie folgt tun:
- die erste Funktion analysiert die Zeichenfolge, und liefert Token (Level, Name) wie (0, 'a'), (1, 'b')
- die zweite Man baut den Baum von dort.

import re 

def tokens(string): 
    # The root name doesn't respect the '= name =' convention, 
    # so we cut the string on the first " = " and yield the root name 
    root_end = string.index(' = ') 
    root, rest = string[:root_end], string[root_end:] 
    yield 0, root 

    # We use a regex for the next tokens, who consist of the following groups: 
    # - any number of "=" followed by 0 or more spaces, 
    # - the name, not containing any = 
    # - and again, the first group of "=..." 

    tokens_re = re.compile(r'(=+ ?)([^=]+)\1') 
    # findall will return a list: 
    # [('= ', 'b '), ('= ', 'c '), ('== ', 'd '), ('== ', 'e '), ('=== ', 'f '), ...] 
    for token in tokens_re.findall(rest): 
     level = token[0].count('=') 
     name = token[1].strip() 
     yield level, name 


def tree(token_list):  
    out = [] 
    # We keep track of the current position in the hierarchy: 
    hierarchy = [] 
    for token in token_list: 
     level, name = token 
     # We cut the hierarchy below the level of our token 
     hierarchy = hierarchy[:level] 
     # and append the current one 
     hierarchy.append(name) 
     out.append('/'.join(hierarchy)) 
    return out 


mystr = 'a = b = = c = == d == == e == === f === === g === ==== h ==== === i === == j == == k == = l =' 
out = tree(tokens(mystr)) 
# Check that this is your expected output 
assert out == ['a', 'a/b', 'a/c', 'a/c/d', 'a/c/e', 'a/c/e/f', 'a/c/e/g', 
      'a/c/e/g/h', 'a/c/e/i', 'a/c/j', 'a/c/k', 'a/l'] 

print(out) 
# ['a', 'a/b', 'a/c', 'a/c/d', 'a/c/e', 'a/c/e/f', 'a/c/e/g', 'a/c/e/g/h', 'a/c/e/i', 'a/c/j', 'a/c/k', 'a/l'] 
Verwandte Themen