我有一个包含多个段落的文档。我想遍历文档的每个段落,检查是否有引号中的单词。如果引号中少于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
这段代码没有检查引文中的单词计数,因为我还没有成功地获得这一点。但至少它会让你知道我想做什么。关于我在这里做错了什么想法?
答案 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
结果:
请注意,删除括号中的位将在后面留下多个连续的空格(上图中以粉红色突出显示的示例)。不确定你是否想要解决这个问题,但如果是这样的话,请注意一下,如果你遇到麻烦就问一个新问题。
答案 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 该方法实际上更简单,它只是在空格上拆分字符串并计算结果数组的长度。