本文的文字及圖片來源于網路,僅供學習、交流使用,不具有任何商業用途,如有問題請及時聯系我們以作處理,
作者:小小明
來源:菜J學Python
Python爬蟲、資料分析、網站開發等案例教程視頻免費在線觀看
https://space.bilibili.com/523606542
需求
有一個下面這種形式的word表格:
希望能轉換為下面這種格式的excel表格:
測驗word檔案讀取
先測驗一個word檔案前1頁的資料讀取:
from docx import Document
doc = Document("編號02 質檢員高級技師(一級)理論試卷.docx")
for i, paragraph in enumerate(doc.paragraphs[:55]):
print(i, paragraph.text)
從讀取效果上看,各行文本資料都能很順利的獲取到,
匹配題型、題目和具體的選項
現在我們需要做的是就是匹配題型、題目和具體的選項,觀察可以發現規律:
- 題型以大寫數字開頭
- 題目以普通數字+.開頭
- 選項以括號+字母開頭
?
額外需要注意的:
開頭幾行文本也存在普通數字+.開頭的,需要直接排除,
第7題的題目,和第19題的選項存在一些特殊的空白字符需要排除,
括號和小數點都同時存在半角和全角兩種情況,
?
對于需要注意的第二點:
查看一下這2處的空白字符:
doc.paragraphs[21].text
'7.(\xa0\xa0)是第一家實施六西格瑪管理的公司,\xa0'
doc.paragraphs[49].text
'(A)引數設計 (B)常量設計\u3000 (C)變數設計\u3000\u3000 (D)系統設計'
發現分別是\xa0和\u3000,
整理好大致思路,我組織一下處理代碼:
import re
from docx import Document
doc = Document("編號02 質檢員高級技師(一級)理論試卷.docx")
black_char = re.compile("[\s\u3000\xa0]+")
chinese_nums_rule = re.compile("[一二三四]、(.+?)\(")
title_rule = re.compile("\d+.")
option_rule = re.compile("\([ABCDEF]\)")
option_rule_search = re.compile("\([ABCDEF]\)[^(]+")
# 從word檔案的“一、單項選擇題”開始遍歷資料
for paragraph in doc.paragraphs[5:25]:
# 去除空白字符,將全角字符轉半角字符,并給括號之間調整為中間二個空格
line = black_char.sub("", paragraph.text).replace(
"(", "(").replace(")", ")").replace(".", ".").replace("()", "( )")
# 對于空白行就直接跳過
ifnot line:
continue
if title_rule.match(line):
print("題目", line)
elif option_rule.match(line):
print("選項", option_rule_search.findall(line))
else:
chinese_nums_match = chinese_nums_rule.match(line)
if chinese_nums_match:
print("題型", chinese_nums_match.group(1))
從目前測驗結果來看沒有問題,
保存匹配到的資料到結構化字典
現在我打算將當前匹配出來的文本資料存盤成字典形式的結構化資料,字典結構的設計如下:
根據上述設計完善代碼:
import re
from docx import Document
from collections import OrderedDict
doc = Document("編號02 質檢員高級技師(一級)理論試卷.docx")
black_char = re.compile("[\s\u3000\xa0]+")
chinese_nums_rule = re.compile("[一二三四]、(.+?)\(")
title_rule = re.compile("\d+.")
option_rule = re.compile("\([ABCDEF]\)")
option_rule_search = re.compile("\([ABCDEF]\)[^(]+")
# 保存最終的結構化資料
question_type2data = https://www.cnblogs.com/hhh188764/p/OrderedDict()
# 從word檔案的“一、單項選擇題”開始遍歷資料
for paragraph in doc.paragraphs[5:]:
# 去除空白字符,將全角字符轉半角字符,并給括號之間調整為中間一個空格
line = black_char.sub("", paragraph.text).replace(
"(", "(").replace(")", ")").replace(".", ".").replace("()", "( )")
# 對于空白行就直接跳過
ifnot line:
continue
if title_rule.match(line):
options = title2options.setdefault(line, [])
elif option_rule.match(line):
options.extend(option_rule_search.findall(line))
else:
chinese_nums_match = chinese_nums_rule.match(line)
if chinese_nums_match:
question_type = chinese_nums_match.group(1)
title2options = question_type2data.setdefault(question_type, OrderedDict())
遍歷結構化字典并存盤
然后我們遍歷結構化字典,將資料保存到pandas物件中:
import pandas as pd
result = []
max_options_len = 0
for question_type, title2options in question_type2data.items():
for title, options in title2options.items():
result.append([question_type, title, *options])
options_len = len(options)
if options_len > max_options_len:
max_options_len = options_len
df = pd.DataFrame(result, columns=[
"題型", "題目"]+[f"選項{i}"for i in range(1, max_options_len+1)])
# 題型可以簡化下,去掉選擇兩個字
df['題型'] = df['題型'].str.replace("選擇", "")
df.head()
結果:
最終保存結果:
df.to_excel("result.xlsx", index=False)
完整代碼
最終完整代碼:
import pandas as pd
import re
from docx import Document
from collections import OrderedDict
doc = Document("編號02 質檢員高級技師(一級)理論試卷.docx")
black_char = re.compile("[\s\u3000\xa0]+")
chinese_nums_rule = re.compile("[一二三四]、(.+?)\(")
title_rule = re.compile("\d+.")
option_rule = re.compile("\([ABCDEF]\)")
option_rule_search = re.compile("\([ABCDEF]\)[^(]+")
# 保存最終的結構化資料
question_type2data = https://www.cnblogs.com/hhh188764/p/OrderedDict()
# 從word檔案的“一、單項選擇題”開始遍歷資料
for paragraph in doc.paragraphs[5:]:
# 去除空白字符,將全角字符轉半角字符,并給括號之間調整為中間一個空格
line = black_char.sub("", paragraph.text).replace(
"(", "(").replace(")", ")").replace(".", ".").replace("()", "( )")
# 對于空白行就直接跳過
ifnot line:
continue
if title_rule.match(line):
options = title2options.setdefault(line, [])
elif option_rule.match(line):
options.extend(option_rule_search.findall(line))
else:
chinese_nums_match = chinese_nums_rule.match(line)
if chinese_nums_match:
question_type = chinese_nums_match.group(1)
title2options = question_type2data.setdefault(
question_type, OrderedDict())
result = []
max_options_len = 0
for question_type, title2options in question_type2data.items():
for title, options in title2options.items():
result.append([question_type, title, *options])
options_len = len(options)
if options_len > max_options_len:
max_options_len = options_len
df = pd.DataFrame(result, columns=[
"題型", "題目"]+[f"選項{i}"for i in range(1, max_options_len+1)])
# 題型可以簡化下,去掉選擇兩個字
df['題型'] = df['題型'].str.replace("選擇", "")
df.to_excel("result.xlsx", index=False)
最終得到的檔案:
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/249329.html
標籤:Python
下一篇:人生苦短,我用Python

