python-pptx:从幻灯片中提取文本时出现奇怪的拆分
python-pptx: Getting odd splits when extracting text from slides
我正在使用 https://python-pptx.readthedocs.io/en/latest/user/quickstart.html 中的 "Extract all text from slides in presentation" 示例从一些 PowerPoint 幻灯片中提取文本。
from pptx import Presentation
prs = Presentation(path_to_presentation)
# text_runs will be populated with a list of strings,
# one for each text run in presentation
text_runs = []
for slide in prs.slides:
for shape in slide.shapes:
if not shape.has_text_frame:
continue
for paragraph in shape.text_frame.paragraphs:
for run in paragraph.runs:
text_runs.append(run.text)
它似乎工作正常,除了我在某些 text_runs 中出现奇怪的分裂。我期望会组合在一起的东西正在被拆分,并且没有我可以检测到的明显模式。例如,有时幻灯片标题分为两部分,有时则不是
我发现我可以通过在幻灯片上重新键入文本来消除奇怪的拆分,但这不会缩放。
我不能,或者至少不想,将拆分文本的两个部分合并在一起,因为有时文本的第二部分已与不同的文本合并 运行。例如,在幻灯片组的标题幻灯片上,标题将一分为二,标题的第二部分与标题幻灯片的副标题文本合并。
关于如何消除奇怪的/不需要的分裂有什么建议吗?还是从 PowerPoint 阅读文本时会出现这种行为 more-or-less?
我想说这绝对是意料之中的事情。 PowerPoint 会随时拆分 运行s,可能是为了突出显示拼写错误的单词,或者只是在您暂停输入或进入更正拼写错误或其他内容时。
关于 运行 唯一可以肯定的是它包含的所有字符共享相同的字符格式。例如,无法保证 运行 就是人们可能所说的 "greedy",包括尽可能多的字符 do 共享相同的字符格式。
如果您想重建 运行 中的 "greedy" 连贯性,这将取决于您,也许使用这样的算法:
last_run = None
for run in paragraph.runs:
if last_run is None:
last_run = run
continue
if has_same_formatting(run, last_run):
last_run = combine_runs(last_run, run)
continue
last_run = run
这让您可以实施 has_same_formatting()
和 combine_runs()
。这里有一定的优势,因为 运行s 可以包含您不关心的差异,例如脏属性或其他任何内容,您可以挑选对您重要的。
has_same_formatting()
实施的开始是:
def has_same_formatting(run, run_2):
font, font_2 = run.font, run_2.font
if font.bold != font_2.bold:
return False
if font.italic != font_2.italic:
return False
# ---same with color, size, type-face, whatever you want---
return True
combine_runs(base, suffix)
看起来像这样:
def combine_runs(base, suffix):
base.text = base.text + suffix.text
r_to_remove = suffix._r
r_to_remove.getparent().remove(r_to_remove)
我正在使用 https://python-pptx.readthedocs.io/en/latest/user/quickstart.html 中的 "Extract all text from slides in presentation" 示例从一些 PowerPoint 幻灯片中提取文本。
from pptx import Presentation
prs = Presentation(path_to_presentation)
# text_runs will be populated with a list of strings,
# one for each text run in presentation
text_runs = []
for slide in prs.slides:
for shape in slide.shapes:
if not shape.has_text_frame:
continue
for paragraph in shape.text_frame.paragraphs:
for run in paragraph.runs:
text_runs.append(run.text)
它似乎工作正常,除了我在某些 text_runs 中出现奇怪的分裂。我期望会组合在一起的东西正在被拆分,并且没有我可以检测到的明显模式。例如,有时幻灯片标题分为两部分,有时则不是
我发现我可以通过在幻灯片上重新键入文本来消除奇怪的拆分,但这不会缩放。
我不能,或者至少不想,将拆分文本的两个部分合并在一起,因为有时文本的第二部分已与不同的文本合并 运行。例如,在幻灯片组的标题幻灯片上,标题将一分为二,标题的第二部分与标题幻灯片的副标题文本合并。
关于如何消除奇怪的/不需要的分裂有什么建议吗?还是从 PowerPoint 阅读文本时会出现这种行为 more-or-less?
我想说这绝对是意料之中的事情。 PowerPoint 会随时拆分 运行s,可能是为了突出显示拼写错误的单词,或者只是在您暂停输入或进入更正拼写错误或其他内容时。
关于 运行 唯一可以肯定的是它包含的所有字符共享相同的字符格式。例如,无法保证 运行 就是人们可能所说的 "greedy",包括尽可能多的字符 do 共享相同的字符格式。
如果您想重建 运行 中的 "greedy" 连贯性,这将取决于您,也许使用这样的算法:
last_run = None
for run in paragraph.runs:
if last_run is None:
last_run = run
continue
if has_same_formatting(run, last_run):
last_run = combine_runs(last_run, run)
continue
last_run = run
这让您可以实施 has_same_formatting()
和 combine_runs()
。这里有一定的优势,因为 运行s 可以包含您不关心的差异,例如脏属性或其他任何内容,您可以挑选对您重要的。
has_same_formatting()
实施的开始是:
def has_same_formatting(run, run_2):
font, font_2 = run.font, run_2.font
if font.bold != font_2.bold:
return False
if font.italic != font_2.italic:
return False
# ---same with color, size, type-face, whatever you want---
return True
combine_runs(base, suffix)
看起来像这样:
def combine_runs(base, suffix):
base.text = base.text + suffix.text
r_to_remove = suffix._r
r_to_remove.getparent().remove(r_to_remove)