Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python/Win32选择和删除Word文档中的行_Python_Ms Word_Pywin32_Win32com - Fatal编程技术网

使用Python/Win32选择和删除Word文档中的行

使用Python/Win32选择和删除Word文档中的行,python,ms-word,pywin32,win32com,Python,Ms Word,Pywin32,Win32com,我正在尝试使用python和win32组件自动化Word(2010)文档(所有文档最多40-50个)。具体来说,需要选择行的一部分,并将其全部替换为某些内容。例如,如果在原始文件中有“标签:096-4296-05A”,我希望它被替换为“标签:\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu”。只有当所有文件中的数字都相同,但实际上并非如此时,使用“搜索和替换”才有效。所以在这种情况下,我希望有一个通用的方法来执行这个任务 所以我想的是,如果通过某种方式,我可以选择包含“标签09

我正在尝试使用python和win32组件自动化Word(2010)文档(所有文档最多40-50个)。具体来说,需要选择行的一部分,并将其全部替换为某些内容。例如,如果在原始文件中有“标签:096-4296-05A”,我希望它被替换为“标签:\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu”。只有当所有文件中的数字都相同,但实际上并非如此时,使用“搜索和替换”才有效。所以在这种情况下,我希望有一个通用的方法来执行这个任务

所以我想的是,如果通过某种方式,我可以选择包含“标签096-4296-05A”的行并删除它,然后再写一行新的内容,比如“标签

为此,我确实查看了@Selection对象,甚至尝试为VB编写一些等效的python代码

以下是我迄今为止所写的:

///

########################
#
#   Purpose : Replace all occurrences of `find_str` with `replace_str`
#             in `word_file
#
#######################

def delete_and_add_line(word_file, find_str, replace_str):
    wdFindContinue = 1
    wdReplaceAll = 2

    # Dispatch() attempts to do a GetObject() before creating a new one.
    # DispatchEx() just creates a new one.
    app = win32com.client.DispatchEx("Word.Application")

    app.Visible = 0
    app.DisplayAlerts = 0
    app.Documents.Open(IP_Directory_Dest + "\\" + word_file) ## (word_file)

    # expression.Execute(FindText, MatchCase, MatchWholeWord,
    #   MatchWildcards, MatchSoundsLike, MatchAllWordForms, Forward,
    #   Wrap, Format, ReplaceWith, Replace)
    app.Selection.Find.Execute(find_str, True, True, \
        False, False, False, True, \
        wdFindContinue, False, replace_str, wdReplaceAll)

    app.Selection.EndKey(Extend=win32com.client.constants.wdExtend)##.Select()

    # determine if the text is selected or not
    if (app.Selection.Type == win32com.client.constants.wdSelectionIP ):
        print 'Nothing is selected'
    else:
        print 'Text Selected '

    # to delete the selected line
    app.Selection.Delete()

    app.ActiveDocument.Close(SaveChanges=True)
    app.Quit()
///

########################
#
#   Purpose : Replace all occurrences of `find_str` with `replace_str`
#             in `word_file
#
#######################

def delete_and_add_line(word_file, find_str, replace_str):
    wdFindContinue = 1
    wdReplaceAll = 2

    # Dispatch() attempts to do a GetObject() before creating a new one.
    # DispatchEx() just creates a new one.
    app = win32com.client.DispatchEx("Word.Application")

    app.Visible = 0
    app.DisplayAlerts = 0
    app.Documents.Open(IP_Directory_Dest + "\\" + word_file) ## (word_file)

    # expression.Execute(FindText, MatchCase, MatchWholeWord,
    #   MatchWildcards, MatchSoundsLike, MatchAllWordForms, Forward,
    #   Wrap, Format, ReplaceWith, Replace)
    app.Selection.Find.Execute(find_str, True, True, \
        False, False, False, True, \
        wdFindContinue, False, replace_str, wdReplaceAll)

    app.Selection.EndKey(Extend=win32com.client.constants.wdExtend)##.Select()

    # determine if the text is selected or not
    if (app.Selection.Type == win32com.client.constants.wdSelectionIP ):
        print 'Nothing is selected'
    else:
        print 'Text Selected '

    # to delete the selected line
    app.Selection.Delete()

    app.ActiveDocument.Close(SaveChanges=True)
    app.Quit()
当我执行这段代码时,我发现app.Selection.Find.execute能够成功地找到并替换提供给它的文本。 即使它打印“选中的文本”,这意味着选中了行尾的文本,但它从不删除选中的行

此外,我不确定这是否是完全选择一行直到其结束的正确方法(使用select时会出现属性错误“AttributeError:'int'对象没有属性“select”)


如果我遗漏了什么,请告诉我。欢迎任何建议。

注意,您正在执行函数“Selection.Find”获取的所有匹配项的替换,然后在最后一次匹配后尝试扩展选择项,我认为这不是您想要的。由于Word不接受此常量(wdExtend),因此扩展选择的方式也出现错误

此外,作为finally子句的一部分关闭文档是一种很好的做法,以避免将单词留在未知状态的内存中

我认为正确的解决方案是迭代文档中的所有段落,然后使用正则表达式匹配并替换要替换的文本。正则表达式比单词find函数强大得多。可以使用“范围属性”的“文本”属性访问段落文本。比如:

import win32com.client
import re

# This is the regular expression to match the text you are after
regexp = "Label: [0-9A-Z-]+"

def replace_label(word_file):
    app = win32com.client.DispatchEx("Word.Application")
    app.Visible = 0
    app.DisplayAlerts = 0
    app.Documents.Open("C:\\" + word_file)
    try:
        doc = app.ActiveDocument
        # Iterate over all the paragraphs
        for parNo in range(1,doc.Paragraphs.Count):
            paragraph = doc.Paragraphs(parNo)
            # Get the text of the paragraph.
            current_text = paragraph.Range.Text
            # Check if there is a match in the paragraph
            if re.search(regexp,current_text):
                # We found a match... do the replace
                paragraph.Range.Text = re.sub(regexp,"Label _______",current_text)
    finally:
        app.ActiveDocument.Close(SaveChanges=True)
        app.Quit()
我不确定我所建议的正则表达式,因此您可能需要对其进行调整。我所知道的正则表达式的最佳指南是:


@Jujara:感谢你的努力。我一定会尝试这些,并得出我的结果。但是,正如您所说,“由于Word不接受此常量(wdExtend),因此扩展选择的方式也有错误。”请确保您已运行makepy文件(通常位于@C:\Python27\Lib\site packages\win32com\client)并选择了“Microsoft Word 14.0对象库(8.5)”除此之外,“从win32com.client导入常量”感谢您提供常量信息。我再次执行了您的原始代码,并发现了一些值得注意的事情:如果您执行查找并替换所有内容,那么您在文档的末尾没有选择项,并且光标在文档的开头结束。如果要保留所选内容,则不应全部替换,可能只能查找。如果您这样调用Selection.EndKey,它的工作原理与您最初希望的一样:app.Selection.EndKey(Unit=wdLine,Extend=wdExtend)。请注意,在任何时候,您都可以通过调用app.Selection.Range()来验证所选内容。顺便说一下,我有一个场景,其中有一个标题/常量文本,如“Call Tree:”出现在Word文档中,然后有一些行,一旦行结束,就有一个表。因此,我希望使用python删除表和标题/常量文本“Call Tree:”之间的行。对此有什么想法/建议吗?