我正在使用Python-Docx读取docx文件,找到特定的字符串(例如,日期),并用另一个字符串(例如,新日期)替换。
这是我正在使用的两个功能:
def docx_replace_regex(doc_obj, regex , replace):
for p in doc_obj.paragraphs:
if regex.search(p.text):
inline = p.runs
# Loop added to work with runs (strings with same style)
for i in range(len(inline)):
if regex.search(inline[i].text):
text = regex.sub(replace, inline[i].text)
inline[i].text = text
for table in doc_obj.tables:
for row in table.rows:
for cell in row.cells:
docx_replace_regex(cell, regex , replace)
def replace_date(folder,replaceDate,*date):
docs = [y for x in os.walk(folder) for y in glob(os.path.join(x[0], '*.docx'))]
for doc in docs:
if date: #Date is optional date to replace
regex = re.compile(r+date)
else: #If no date provided, replace all dates
regex = re.compile(r"(\w{3,12}\s\d{1,2}\,?\s?[0-9]{4})|((the\s)?\d{1,2}[th]{0,2}\sday\sof\s\w{3,12}\,\s?\d{4})")
docObj = Document(doc)
docx_replace_regex(docObj,regex,replaceDate)
docObj.save(doc)
第一个函数本质上是一个查找和替换函数,用于将python与docx文件一起使用。第二个文件以递归方式搜索文件路径,以找到要搜索的docx文件。正则表达式的细节无关紧要(我认为)。它实际上搜索不同的日期格式。它可以按我的意愿运行,并且不会影响我的问题。
[将文档传递给docx_replace_regex时,该函数将遍历各个段落,然后运行并在运行中搜索我的正则表达式。问题是,运行有时会分解一行文本,因此如果文档为纯文本格式,则正则表达式将捕获文本,但是由于运行会分解文本,因此不会捕获文本。
例如,如果我的段落是“ 2020年5月10日”,则内联数组可能是['1','0th day of May,',' 2020']
。
最初,我加入了内联数组,因此它等于“ 2020年5月10日”,但是由于我的内联变量是字符串,而不是运行对象,所以我无法用新文本替换运行。即使我将内联保持为运行对象,它仍将仅替换我要查找的文本的一部分。
正在寻找有关如何正确替换我的正则表达式捕获的文本部分的任何想法。或者,为什么将句子按原样分成单独的部分。
这不是一个简单的问题,因为您似乎已经开始意识到:)
最简单的方法是在paragraph.text
中进行搜索和替换,例如:
paragraph.text = my_replace_function(paragraph.text, ...)
这有效,但是所有字符格式都会丢失。一种更复杂的方法是找到搜索短语的偏移量,将其映射到运行,然后根据需要拆分并重新加入运行,以仅更改包含搜索短语的那些运行。
[这里似乎有一个可行的解决方案:https://stackoverflow.com/a/55733040/1902513,它通过其长度显示了所涉及的数量。
它已经出现好几次了,所以如果您在[python-docx] replace
的SO中搜索,您会发现更多关于问题性质的信息。