如何用VBA与RegExp保留CRLF提取两个日期字符串间文本
解决Word VBA正则提取时丢失换行(CRLF)的问题
问题场景
文档内容示例:
5/1/2023 blah blah blah 4/1/2023 jabber jabber jabber
预期提取两个日期之间的内容(保留换行):
blah blah blah
但实际提取结果丢失了所有换行:
blahblahblah
用户原VBA代码
Function getLastNote() 'extracts content between two date strings. The result should be the latest note entry Dim regEx As Object, matchCollection As Object, extractedString As String Set regEx = CreateObject("VBScript.RegExp") With regEx .IgnoreCase = True .Global = False ' Only look for 1 match; False is actually the default. .Pattern = "\d{1,2}\/\d{1,2}\/\d{4}((.|\n)*?)\d{1,2}\/\d{1,2}\/\d\d\d\d" End With Set matchCollection = regEx.Execute(ActiveDocument.Content.text) If matchCollection.Count > 0 Then ' Extract the first submatch's (capture group's) value - getLastNote = matchCollection(0).submatches(0) Else getLastNote = ActiveDocument.Content 'there's no match so return the text of the doc. End If End Function
问题原因
- Word文档的文本中,段落换行是段落标记(对应VBA的
vbCr,正则里为\r),而非普通的\n,原正则里的\n无法匹配Word的换行符。 (.|\n)的写法在VBScript正则中不能可靠匹配所有换行场景,且效率较低。- Else分支直接返回
ActiveDocument.Content对象而非文本内容,存在逻辑问题。
解决方案
修改正则表达式,用[\s\S]匹配任意字符(包括换行),同时修正Else分支的返回值:
Function getLastNote() 'extracts content between two date strings. The result should be the latest note entry Dim regEx As Object, matchCollection As Object, extractedString As String Set regEx = CreateObject("VBScript.RegExp") With regEx .IgnoreCase = True .Global = False ' Only look for 1 match; False is actually the default. .Pattern = "\d{1,2}\/\d{1,2}\/\d{4}([\s\S]*?)\d{1,2}\/\d{1,2}\/\d{4}" End With Set matchCollection = regEx.Execute(ActiveDocument.Content.Text) If matchCollection.Count > 0 Then ' Extract the first submatch's (capture group's) value - getLastNote = matchCollection(0).submatches(0) Else getLastNote = ActiveDocument.Content.Text '返回文档文本而非对象 End If End Function
修改说明
[\s\S]*?:\s匹配任意空白字符(包括Word的段落标记\r),\S匹配非空白字符,组合后能匹配所有字符,确保包含换行的内容被完整捕获。- 修正Else分支返回
ActiveDocument.Content.Text,保证无论是否匹配成功,返回的都是文本格式内容。
内容的提问来源于stack exchange,提问作者Dirigo
相关产品推荐
相关产品推荐

