2016-07-25 9 views
0

Nehmen wir an, dass ich eine Probe der folgenden Zeichenketten haben:Wie man bestimmte Wörter aus einer Liste extrahiert, wenn sich die Listenlänge ändert?

  • string = ‚http/1.1 abc-ad-sd-00 .sad.sdsd.der.net (Server/1.2 [dsddsf tat : t yy p sS]), http/1.1 asc-ad-sd-11 .sad.sdsd.der.net (Server/1.2 [gfef srFw: t reri pss]) '
  • string1 =' http/1.1 abc-ad-sd-01 .sad.sdsd.der.net (Server/1.2 [dsddsf fu tat: t yy p sS]), http/1.1 asc-ad-sd-13 .sad .sdsd.der.net (Server/1.2 [ als srFw SFF: t reri pss]) '
  • string2 =' http/1.1 abc-ad-sd-002 .sad.sdsd.der.net (Server/1.2 [dsddsf tat t yy p sS ]), HTTP/1.1 ASC-ad-SD-14 .sad.sdsd.der.net (Server/1.2 [rts als f srFw: t reri Pss]) '
  • string3 =' http/1.1 abc-ad-sd-03 .sad.sdsd.der.net (Server/1.2 [dsddsf tat: tyy p sS]), http/1.1 asc-ad-sd-15 .sad.sdsd.der .net (Server/1.2 [tttts als t srFw: t reri pSs]) '

Hier ist, was ich tat, die kühnen Saiten zu erhalten:

If name == 'via': 

name = “ID1” 
string = header_line.split(' ') 
b = (string[2].split('.')) 
value = b[0] 
headers[name] = value 

#----------# 

name_1 = “ID2” 
string = header_line.split(' ') 
b_1 = (string[9].split('.')) 
value_1 = b_1[0] 
headers[name_1] = value_1 

#-----# 

name_2 = “ID3” 
string = header_line.split(' ') 
b_2 = (string[11:]) 
value_2 = ''.join(b_2) 
headers[name_2] = value_2 

#----# 

Das Problem dabei ist, dass es nur in bestimmten Situationen funktioniert. Wie Sie sehen können, gibt es 3 verschiedene Strings, so dass die fett gedruckten Strings nicht richtig funktionieren. Natürlich ist das nicht mein vollständiger Code, da diese Zeichenfolgen in der dict-Liste gespeichert sind. Beispiel: Meine erste Ausgabe sieht wie folgt aus:

[{ 'item1': '10574', 'Element2': '69 .241.51.134' , 'über': ‚http/1.1 abc-ad-sd -00.sad.sdsd.der.net (Server/1.2 [dsddsf tat: t yy p sS]), http/1.1 asc-ad-sd-11.sad.sdsd.der.net (Server/1.2 [tttts srFw : t RERI Pss]))‘, 'item4': '22', 'HTTP-Antwort': [ 'HTTP/1.1 200 OK \ r \ n']}, {...}, {...}]

Und ich möchte eine andere Ausgabe wie diese basierend auf den analysierten Werten aus der obigen Antwort.

[{ 'item1': '10574', 'Element2': '69 .241.51.134' , 'ID3': 'tttts srFw: t reri pss', 'item4': '22', 'ID2' : 'asc-ad-sd-11', 'HTTP-ANTWORT': ['HTTP/1.1 200 OK \ r \ n'], 'ID1': 'abc-ad-sd-00'}, {...}, { ...}]

so wie Sie sehen können, ich habe Haufen dicts in einer Liste und für den Schlüssel ‚über‘, will ich seinen Wert in verschiedenen Teil analysiert werden, die ich will und speichern sie in neuen Schlüsselwerte. Ich habe das bereits in meinem Code getan.

Update: Vielen Dank für Ihre Antworten. Ich habe meine Frage geklärt. Aus Ihrer Antwort funktioniert der Wert für ID1 und ID2, der Wert innerhalb von [] funktioniert jedoch nicht, da "tttts" nicht in jeder Antwort dieselbe Zeichenfolge ist.

Ein weiteres Update: Vielen Dank für Ihre Hilfe! Mit der Antwort von allen habe ich meinen Code ein wenig optimiert und herausgefunden, wie man die Werte bekommt.

+0

Wenn Ihre Frage elegantere war ich versucht hätte mehr zu helfen, aber es scheint, dass Sie versuchen müssen, mit regulären Ausdrücken: http://stackoverflow.com/documentation/python/632/regular-expressions# t = 201607251447256330505 –

+0

Vielen Dank für Ihren Kommentar. Bitte sehen Sie sich die aktualisierte Frage an und lassen Sie mich wissen, wenn Sie eine Klärung benötigen. – shishh03

Antwort

0

Ich denke, dass reguläre Ausdrücke dein Freund hier sind. So etwas wie http\/1\.1 ([^\.]+) funktioniert für diesen speziellen Fall.

import re 
match = re.compile('http\/1\.1 ([^\.]+)').search(string) 
value = match.group(1) 

Ich würde empfehlen, die Saiten mit string.split(',') Aufspalten oder was auch immer arbeitet jeden http Eintrag zu spalten.

Sie können mehr über Python-Modul für reguläre Ausdrücke lernen here, und Sie können unsere Ihre regulären Ausdrücken in verschiedenen Websites testen, wie ich this one.

0

in meinem opinionm Sie regex Teilzeichenfolge bekommen können.

import re 
pattern1 = r'\w+-\w+-\w+-\d+' 
pattern2 = r'\[tttts .+\]' 

#s is string you are checking 
#pattern 1 will find substring like abc-ad-sd-00 
re.findall(pattern1,s) 
#pattern 2 will find substring like [tttts as t srFw:t reri pSs ] 
re.findall(pattern2,s) 

Beispiel:

s = 'http/1.1 abc-ad-sd-00.sad.sdsd.der.net (Server/1.2 [dsddsf did:t yy p sS]), http/1.1 asc-ad-sd-11.sad.sdsd.der.net (Server/1.2 [tttts srFw:t reri pSs ])' 

re.findall(r'\[tttts .+\]',s) 
['[tttts srFw:t reri pSs ]'] 
re.findall(r'\w+-\w+-\w+-\d+',s) 
['abc-ad-sd-00', 'asc-ad-sd-11'] 
0

Wie Sie mit viel Text arbeiten, dann die erste Sache ist, Gebrauch zu machen/eine effiziente Speicher-fiendly Iterator über die Saiten erstellen. (nehmen wir an, Sie setzen es in Funktion line_iterator)

Die zweite Sache zu tun ist, verwenden Sie einen regulären Ausdruck für die erforderlichen Teile von Zeichenfolgen (vorausgesetzt, Sie geschrieben und kompiliert die Regexp). Wenn in jeder Zeichenfolge immer 2 ähnliche Teile vorhanden sind, fügen Sie sie in Ihrem regulären Ausdruck in Gruppen ein.

Dann können Sie etwas tun:

import re 

regexp = re.compile('<you regular expression>') 

for line in line_iterator(): 
    match = regexp.match(line) 
    if match: 
     write_to_csv(match.groups()) 

Wie auch immer, haben Sie einen Blick auf regular expressions, sie sind es wert

Hinweis: 1. Ihre regulären Ausdruck zusammenstellen (s), wenn Sie brauchen um es viel zu benutzen; 2. Verwenden Sie Generatoren zum Iterieren über Strings, halten Sie nicht alle im Speicher; 3. besser verwenden Sie 1 regulären Ausdruck, wenn Sie können

0

Checkout positive lookbehind regular expression.

import re 

p = """string = 'http/1.1 abc-ad-sd-00.sad.sdsd.der.net (Server/1.2 [dsddsf did:t yy p sS]), http/1.1 asc-ad-sd-11.sad.sdsd.der.net (Server/1.2 [tttts srFw:t reri pSs ])' 
string1 = 'http/1.1 abc-ad-sd-01.sad.sdsd.der.net (Server/1.2 [dsddsf f u did:t yy p sS]), http/1.1 asc-ad-sd-13.sad.sdsd.der.net (Server/1.2 [tttts as srFw:t reri pSs ])' 
string2 = 'http/1.1 abc-ad-sd-002.sad.sdsd.der.net (Server/1.2 [dsddsf did:t yy p sS]), http/1.1 asc-ad-sd-14.sad.sdsd.der.net (Server/1.2 [tttts as f srFw:t reri pSs ])' 
string3 = 'http/1.1 abc-ad-sd-03.sad.sdsd.der.net (Server/1.2 [dsddsf did:t yy p sS]), http/1.1 asc-ad-sd-15.sad.sdsd.der.net (Server/1.2 [tttts as t srFw:t reri pSs ])' 
""" 
s = re.findall("(?<=http/1.1\s)([\w\d\-]*)", p, re.DOTALL | re.MULTILINE) 
s2 = re.findall("(?<=Server/1.2\s)\[([\w:\s]*)\]", p, re.DOTALL | re.MULTILINE) 
print(list(s)) 
print(list(s2)) 

# will prints 
# ['abc-ad-sd-00', 'asc-ad-sd-11', 'abc-ad-sd-01', 'asc-ad-sd-13', 'abc-ad-sd-002', 'asc-ad-sd-14', 'abc-ad-sd-03', 'asc-ad-sd-15'] 

# and 
# ['dsddsf did:t yy p sS', 'tttts srFw:t reri pSs ', 'dsddsf f u did:t yy p sS', 'tttts as srFw:t reri pSs ', 'dsddsf did:t yy p sS', 'tttts as f srFw:t reri pSs ', 'dsddsf did:t yy p sS', 'tttts as t srFw:t reri pSs '] 
0

regex verwenden Sie können einen Ausdruck, bevor Sie Ihre Schleife zusammenstellen und jede ID Sie von jeder Zeichenfolge, wie Sie Schleife über sie wollen bekommen. Der erste Regex erhält die ersten beiden IDs, die das gleiche Format haben. \w+ sucht nach mindestens einem Wort und \d+ sucht nach mindestens einer Ziffer. Der zweite Ausdruck möchte das zweite Vorkommen dessen, was in den Klammern steht, also beginnen Sie mit \[.*? und suchen dann nach mindestens einem Wort und einem Leerzeichen vor dem Rest des Ausdrucks.

import re 

list_of_strings=[ 
    'http/1.1 abc-ad-sd-00.sad.sdsd.der.net (Server/1.2 [dsddsf did:t yy p sS]), http/1.1 asc-ad-sd-11.sad.sdsd.der.net (Server/1.2 [gfef srFw:t reri pSs ])', 
    'http/1.1 abc-ad-sd-01.sad.sdsd.der.net (Server/1.2 [dsddsf f u did:t yy p sS]), http/1.1 asc-ad-sd-13.sad.sdsd.der.net (Server/1.2 [sff as srFw:t reri pSs ])', 
    'http/1.1 abc-ad-sd-002.sad.sdsd.der.net (Server/1.2 [dsddsf did:t yy p sS]), http/1.1 asc-ad-sd-14.sad.sdsd.der.net (Server/1.2 [rts as f srFw:t reri pSs ])', 
    'http/1.1 abc-ad-sd-03.sad.sdsd.der.net (Server/1.2 [dsddsf did:t yy p sS]), http/1.1 asc-ad-sd-15.sad.sdsd.der.net (Server/1.2 [tttts as t srFw:t reri pSs ])' 
    ] 

first_ids=r'\w+-\w+-\w+-\d+' 
last_id=r'\[.*\[(\w+\s.*\w+:\w+\s\w+\s\w+)' 
for url in list_of_strings: 
    print(url) 
    print(re.findall(first_ids,url)[0]) 
    print(re.findall(first_ids,url)[1]) 
    print(re.findall(last_id,url)[0]) 
+0

Vielen Dank für Ihren Kommentar. Bitte sehen Sie sich die aktualisierte Frage an und lassen Sie mich wissen, wenn Sie eine Klärung benötigen. Getting the first_ids funktionierte jedoch, für die letzte_id, wird es nicht immer "tttts" so versuchen, dieses Muster zu treffen, funktioniert in meinem Fall nicht:/ – shishh03

+0

Aber wenn Sie die Antwort anderer betrachten, können wir vielleicht "Server/1.2 "in (Server/1.2 [tttts als t srFw: t reri pSs] und bekomme nur die [tttts als t srFw: t reri pSs]. Anstatt" tttts "zu entsprechen. – shishh03

+0

@ shishh03 aktualisiert die Regex, um mit den neuen Strings zu arbeiten – depperm

Verwandte Themen