VBA批量把WORD中的网址转换为超链接

VBA批量把WORD中的网址转换为超链接

在用印象笔记和word整理微信聊天记录时会遇到这种类型的段落

图1:微信聊天记录中的链接在word中的格式

这些原始记录在微信里如图2所示

图2:链接在微信里的格式

需要整理发布到公众号上的格式如下图图3所示

图3:超链接在公众号里的格式

如果直接复制粘贴过来在公众号编辑器里,当然不是图3这种格式。一种处理的方式是,在编辑器里,手动处理,选中超链接文本,剪切,选中前面的标题文本,点击编辑超链接。

图4:微信公众号里编辑超链接


图5:微信公众号里编辑超链接

这样做很容易出错,因为微信公众号的文章分享出来的时候,后面的链接很长,而且没有什么可以优化缩短的规律,链接多了还容易遗漏。好在微信公众号支持WORD文档导入,我们可以在把这些工作放在WORD里用宏自动完成。

到了发挥杀鸡要用牛刀的精神的时候了,假设我们遇到一个问题,不要一直用笨办法绕过这个问题,试着用不同的表述方式去搜索这个问题。

只要你有一个准确的问题,99.9%的可能性你会找到一个不错的答案。

但最近遇到的这几个问题,都属于那0.1%的范畴。

如果努力之后确定答案不属于那99.9%,那么我们就努力扩大一下这99.9%的范围。

第一步:观察文本特征

聊天记录里出现的带有http链接的段落,是我们要整理的目标对象,例如

图6:带有链接的文本段落示例1


图7:带有链接的文本段落示例2

但是微信公众号里仅支持在微信公众号平台发布的文章链接

图8:微信公众号不支持外部链接

所以我们只需要整理来自微信公众号的链接文本。接下来观察这些段落的文本特征,用正则表达式写出来 第二步:用正则表达式匹配 用strSearch来代表搜索关键词的变量,通过开头的网址【 mp.weixin.qq.com 】即可定位到微信公众号的链接,正则表达式写为

strSearch = "([[])(*http://mp.weixin.qq.com*)([]])"

这里总共有三个圆括号第一个圆括号,代表的是该段以左方括号开头,需要用一个元字符左右方括号括起来才可以

第二个圆括号里的内容分为三部分,左侧和右侧的星号*,表示可以匹配微信公众号网址两端的任意长度的内容。

第三个圆括号,逻辑和第一个一样,代表的是该段以右方括号开头,需要用一个元字符左右方括号括起来才可以。

如果没有第一个和第三个圆括号,那么这个正则表达式匹配的范围就会扩大,出现误选。测试一下,出现下面这样的匹配

图9:正则表达式误匹配

分析一下误选的原因,是因为http前面的星号*,这个通配符表示的是可以匹配任意长度的文本。

图10:误匹配分析

结果就把上一个包含“[”的文本开头匹配上了,这不是我们想要的结果。所以我们需要重新分析含有超链接段落的文本独特特征,需要对这里的通配符“*”做调整。

由于http前面和方括号之间对应的是文章标题,而微信的文章标题其实是有规律可循的

图11:微信公众号标题示意

微信公众号的文章标题长度不能超过64个字符。那么我们就可以用限定方括号和http文本之间的字符长度来做到精确匹配。文章标题的长度是1到64,字符类型不设限制,这个表达式尝试写为

(?{1,64})

在一般的编程语言正则表达式里,代表任意单个字符的元字符是点".",但是在word VBA语言里,代表单个字符的元字符不是点,而是问号“?”更新后的正则表达式写为。

strSearch = "([[])(?{1,64})(: http://mp.weixin.qq.com*)([]])"

继续进行测试

图12:修改后的匹配效果

还是出现了过度匹配,看来通过“?”限定字符长度的方式是走不通了。具体的原因,我找了很多资料,请教了专家,暂时也没找到合适的分析。

还有一种思路是限定字符类型,也就是把这里的问号“?”替换为中文,英文,数字和标点符号这些标题里常用的字符集合,然后限定一下标题长度。但是风险是可能哪一次标题里出现了不在字符集合里的字符,就会匹配错误。这个我进行过测试,可以正常匹配,表达式的长度比较长,就不放在这里了。

再换一个思路,先不在正则表达式这里纠结, 问题的解决往往不在问题的发生层面 。我们把含有超链接的段落的正则表达式先精简一些改为

strSearch = "([[])(*)([]])"


图13:修改后的正则表达式匹配效果

也就是说,我们先匹配含有超链接的所有段落,或者说所有以左右方括号开头结尾的段落,然后再用If函数进行判断,这个段落里是否还有特定的关字符:【 mp.weixin.qq.com

这里用instr函数求出微信公众号文章链接的特定字符【 mp.weixin.qq.com 】在目标段落里出现的位置,如果有,返回的数值肯定大于1,如果没有就是0。这样就解决了精确识别含有微信公众号文章链接的问题。 第三步:编写并调试VBA代码

完整代码如下

Sub 微信公众号超链接批量整理()
    Dim strSearch As String
    Dim mypos As Integer
    strSearch = "([[])(*)([]])" '适用于微信公众号,因为微信公众号仅支持公众号内的文章链接作为超链接。?{1,64}不能有效表示对字符长度的限制
    '可以在正则表达式里用较为简单的
    Selection.HomeKey unit:=wdStory '从头开始搜索,需要把默认光标调整到文档起始位置
    Selection.Find.ClearFormatting
    With Selection.Find '不能用ActiveDocument.Content.Find,不支持正则表达式,需要调整一下查找函数,改为对段落文本进行查找
        .Text = strSearch
        .Forward = True
        .Format = False
        .MatchWildcards = True
        Do While .Execute
        t = Selection.Range.Text
        mypos = InStr(1, t, "http://mp.weixin.qq.com")
            If mypos <> 0 Then
                n = ActiveDocument.Range(0, Selection.Range.End).Paragraphs.Count '返回当前循环过程中p1对应的段落序号
                adress = "http://mp.weixin.qq.com" & Replace(Split(Selection.Range.Text, "http://mp.weixin.qq.com")(1), "]", "")
                title = Replace(Replace(Split(Selection.Range.Text, "http://mp.weixin.qq.com")(0), "[", ""), ":", "")
                ActiveDocument.Paragraphs(n).Range.Delete
                ActiveDocument.Hyperlinks.Add Anchor:=Selection.Range, Address:= _
                   adress _
            , TextToDisplay:=Replace("《" & title & "》", " ", "") & vbCr