如果引号之间的文本少于3个单词,则在括号之间删除文本

时间:2015-03-19 19:42:11

标签: vba ms-word word-vba

我有一个包含多个段落的文档。我想遍历文档的每个段落,检查是否有引号中的单词。如果引号中少于3个单词,我想删除括号内的所有文本外观。

想象一下以下段落。

  

您需要包含的信息取决于材料来自何种类型的来源。对于“印刷材料”,您通常只需要包括作者(s) (或文章标题,如果没有作者)和出版年份(从不您的参考资料中的月份或日期。在引用来源的特定部分(例如,直接引用)时,您还需要指明页码(s)或其他名称(章,图,表,方程等。)。对于Internet源,当页码不可用时,可以使用段落编号。

由于短语“print material”只包含2个单词,我想删除括号中的所有单词和括号本身。

如何在Microsoft Word中使用VBA进行类似的操作?我发布了一些失败的代码,试图表明这是一个真诚的问题。

Sub RemoveUnnecesaryTexts()

Dim doc As Document
Dim para As Paragraph

Set doc = ActiveDocument

For Each para In doc.Paragraphs
    Application.ScreenUpdating = False
    Selection.HomeKey Unit:=wdStory
    With Selection.Find
        .ClearFormatting
        .Text = "(""<*>"")"
    End With

    If Selection.Find.Execute Then
        Selection.Parent.Select
        With Selection.Find
            .Text = "\((<*>)\)"
            .Replacement.Text = ""
            .Forward = True
            .Wrap = wdFindContinue
            .Format = False
            .MatchCase = False
            .MatchWholeWord = False
            .MatchWildcards = False
            .MatchSoundsLike = False
            .MatchAllWordForms = False
        End With
        Selection.Find.Execute Replace:=wdReplaceAll

    End If
Next para

End Sub  

这段代码没有检查引文中的单词计数,因为我还没有成功地获得这一点。但至少它会让你知道我想做什么。关于我在这里做错了什么想法?

2 个答案:

答案 0 :(得分:1)

根据我之前的回答:Format number between markers as subscript

这对我有用:

Dim wd As Document
Dim para As Paragraph
Dim rOpeningQuote As Range
Dim rClosingQuote As Range
Dim rBewteenQuotes As Range
Dim quoteFound As Boolean
Dim nWordsBetweenQuotes As Long
Dim rOpeningParenthesis As Range
Dim rClosingParenthesis As Range
Dim openingParenthesisFound As Boolean

Set wd = ActiveDocument

For Each para In wd.Paragraphs
    para.Range.Select
    'Look for opening quote
    quoteFound = Selection.Find.Execute("""")
    If quoteFound Then
        Set rOpeningQuote = Selection.Range
        'Look for closing quote
        Selection.Find.Execute """"
        Set rClosingQuote = Selection.Range
        'Count words between the two
        Set rBewteenQuotes = wd.Range(rOpeningQuote.End, rClosingQuote.Start)
        nWordsBetweenQuotes = UBound(Split(rBewteenQuotes.Text, " ")) + 1

        If nWordsBetweenQuotes < 3 Then
            para.Range.Select
            Do
                'Look for opening parenthesis
                openingParenthesisFound = Selection.Find.Execute("(")
                If Not openingParenthesisFound Then Exit Do
                Set rOpeningParenthesis = Selection.Range
                'Look for closing parenthesis
                wd.Range(Selection.End, para.Range.End).Select
                Selection.Find.Execute ")"
                Set rClosingParenthesis = Selection.Range
                'Delete and select rest of paragraph for next iteration
                wd.Range(rOpeningParenthesis.Start, rClosingParenthesis.End).Delete
                wd.Range(Selection.End, para.Range.End).Select
            Loop
        End If
    Else
        'No quote found in this paragraph. Do nothing.
    End If
Next para

结果:

enter image description here

请注意,删除括号中的位将在后面留下多个连续的空格(上图中以粉红色突出显示的示例)。不确定你是否想要解决这个问题,但如果是这样的话,请注意一下,如果你遇到麻烦就问一个新问题。

答案 1 :(得分:0)

伪代码:

Iterate through the paragraphs. 
Regex Match the quoted sub string "...." and then count the spaces in the match
If spaces < 2 then 
    Second Regex match all occurrences of (....) and delete all matches in the paragraph 
Else 
    Continue to next paragraph 

请注意,这取决于仅存在一个引用的子字符串。如果情况并非如此,则必须实施逻辑以选择正确的引号。

编辑:我远不是一个正则表达式专家,但匹配可以简单:

String match1 = "/".*/""
String match2 = "/(.*/)"

这些将贪婪地匹配您的预期模式,这意味着它们将匹配“1”,“12345”,(123456 .... 1223447748557),以及空字符串“”和空括号()。如果不需要空箱,则用'+'切换'*'。

我没有测试过这个,我只是破解了正则表达式,直到他们按照我的意愿行事。此外,您需要处理(或忽略)引号内出现的括号。

此外,对于您选择实现此语言的任何语言,您可以逐个字符地迭代匹配的引用子字符串,如果字符是空格,则递增计数器,或者更好:查看您的内容中是否有函数字符串库,将为您执行此操作。

最后,对于某些语言,你应该有一个String.replace()函数,在这种情况下,我会遍历每个括号匹配并将匹配提供给函数,如Paragraph.replace(matches [i],“ “),它只是用空字符串替换你的匹配。

编辑: 哦。我不知何故错过了VBA标题的一部分。然后你需要处理Word的对象模型。 AFAIK有一个Document对象应该返回一个可以迭代的Paragraph []集合。我知道VBA有一个你可以使用的Regex类,String方法应该可行。不确定VBA是否有'int HowManyTimesDoesThisCharAppearInThisString(String search,char target)',但自己实现它并不困难。可以在MSDN上查看字符串文档。这是我唯一喜欢使用M $代码的东西,有一个比平均机会更好的其他人遇到与你相同的问题,并且MSDN非常有代表性。

另外,我发现这一点,可能对您有所帮助:Counting the Words in a String 该方法实际上更简单,它只是在空格上拆分字符串并计算结果数组的长度。