5 回答

TA貢獻(xiàn)1840條經(jīng)驗(yàn) 獲得超5個贊
以下代碼片段將生成一個字典列表,日志文件中的每一行都有一個字典。
import re
def parse_log(log_file):
regex = re.compile(r'^([0-9\.]+) - (.*) \[(.*)\] (".*")')
def _extract_field(match_object, tag, index, result):
if match_object[index]:
result[tag] = match_object[index]
result = []
with open(log_file) as fh:
for line in fh:
match = re.search(regex, line)
if match:
fields = {}
_extract_field(match, 'host' , 1, fields)
_extract_field(match, 'user_name', 2, fields)
_extract_field(match, 'time' , 3, fields)
_extract_field(match, 'request' , 4, fields)
result.append(fields)
return result
def main():
result = parse_log('log.txt')
for line in result:
print(line)
if __name__ == '__main__':
main()

TA貢獻(xiàn)1772條經(jīng)驗(yàn) 獲得超8個贊
我現(xiàn)在正在做這門課程,我得到的答案是
import re
def logs():
with open("assets/logdata.txt", "r") as file:
logdata = file.read()
# YOUR CODE HERE
pattern='''
(?P<host>[\w.]*)
(\ -\ )
(?P<user_name>([a-z\-]*[\d]*))
(\ \[)
(?P<time>\w.*?)
(\]\ \")
(?P<request>\w.*)
(\")
'''
lst=[]
for item in re.finditer(pattern,logdata,re.VERBOSE):
lst.append(item.groupdict())
print(lst)
return lst

TA貢獻(xiàn)1826條經(jīng)驗(yàn) 獲得超6個贊
使用str.split()andstr.index()也可以工作,忽略正則表達(dá)式的需要。此外,您可以直接迭代文件處理程序,這會逐行生成一行,因此您不必將整個文件加載到內(nèi)存中:
result = []
with open('logdata.txt') as f:
for line in f:
# Isolate host and user_name, discarding the dash in between
host, _, user_name, remaining = line.split(maxsplit=3)
# Find the end of the datetime and isolate it
end_bracket = remaining.index(']')
time_ = remaining[1:end_bracket]
# Slice out the time from the request and strip the ending newline
request = remaining[end_bracket + 1:].strip()
# Create the dictionary
result.append({
'host': host,
'user_name': user_name,
'time': time_,
'request': request
})
from pprint import pprint
pprint(result)

TA貢獻(xiàn)1865條經(jīng)驗(yàn) 獲得超7個贊
一旦您解決了您遇到的正則表達(dá)式問題 - 下面的代碼將適合您
import re
result = []
with open('data.txt') as f:
lines = [l.strip() for l in f.readlines()]
for logdata in lines:
host = (re.findall('(.*?)\-',logdata))
username = re.findall('\-(.*?)\[',logdata)
_time = re.findall('\[(.*?)\]', logdata)
request = re.findall('\"(.*?)\"',logdata)
result.append({'host':host,'user_name':username,'time':_time,
'request':request})
print(result)

TA貢獻(xiàn)1797條經(jīng)驗(yàn) 獲得超6個贊
assets/logdata.txt下面的函數(shù)返回一個字典列表,其中包含根據(jù)您的原始問題每行匹配的所需鍵/值。
值得注意的是,應(yīng)在此基礎(chǔ)上實(shí)施適當(dāng)?shù)腻e誤處理,因?yàn)榇嬖诿黠@的邊緣情況可能會導(dǎo)致代碼執(zhí)行意外停止。
請注意您的模式的變化host,這很重要。示例中使用的原始模式不僅僅匹配host每行的部分,在模式開頭添加錨點(diǎn)會re.MULTILINE停止匹配誤報,這些誤報將與原始示例中的每行的其余部分匹配。
import re
def logs():
with open("assets/logdata.txt", "r") as file:
logdata = file.read()
host = (re.findall('^(.*?)\-',logdata, re.MULTILINE))
username = re.findall('\-(.*?)\[',logdata)
time = re.findall('\[(.*?)\]', logdata)
request = re.findall('\"(.*?)\"',logdata)
return [{ "host": host[i].strip(), "username": username[i], "time": time[i], "request": request[i] } for i,h in enumerate(host)]
以上是基于您原始帖子的簡單/最小解決方案。有很多更干凈、更有效的方法可以解決這個問題,但是我認(rèn)為從您現(xiàn)有的代碼開始工作,讓您了解如何糾正它是相關(guān)的,而不僅僅是為您提供一個更好的優(yōu)化解決方案,相對而言,對你來說意義不大。
添加回答
舉報