ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 5214|回复: 17

[讨论] 正则表达式实测慢于VBA查找

[复制链接]

TA的精华主题

TA的得分主题

发表于 2018-6-20 00:35 | 显示全部楼层 |阅读模式
* 最近几天,又对《正则表达式》有了浓厚兴趣,搜集了一些《正则表达式》的 PDF 电子文档,准备有时间学习学习。
* 又反复复习重温了 杜先生《正则表达式》关于修改格式及查找替换的原创代码及相关语录,昨天算正式入门。
* 这几天想用 杜先生 原来为我编的《标题2345自动设置)宏(Title2345),以期提高排版速度。
* 但刚刚我通过简单文本(一页)及巨大文本(50页)测试,发现《正则表达式》并非那么美好!
*杜先生 及各位朋友如有意见,请批评指正,谢谢!
*对比如下:
* 我的//Selection/DoLoop/查找设置标题2345费时:.53/.39/8.4(50页巨大文本)
*杜先生/////正则表达式///查找设置标题2345费时:.71/.67/27.75(50页巨大文本)

TA的精华主题

TA的得分主题

发表于 2018-6-20 07:58 来自手机 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 zhanglei1371 于 2018-6-20 08:14 编辑

很早前我就发现了,而且文档中有域的时候正则表达式的firstindex会出现定位不准的问题。如一个文档中有很多seq的自动编号域,使用正则能正确的匹配到值value,但是选中的range却不正确。问了很多人也无法解决。

TA的精华主题

TA的得分主题

发表于 2018-6-20 08:52 来自手机 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 duquancai 于 2018-6-20 09:08 编辑

因为你根本没有入门,所以有这样的见解!世上本无绝对的好也无绝对的坏!!!
如果你入门了,你也不会发此帖,因为此帖就是入门级问题,最起码的“适用环境”的这个基本道理你就没搞明白,还敢说“正式入门”,你都不知道门在哪里!!!我用“三个感叹号结束吧”

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-20 09:41 | 显示全部楼层
zhanglei1371 大师好!——这个“域”问题,我看 杜先生 语录时注意到了,应用正则前要删除所有域。
杜先生 好!——我前两天,做了第一次尝试:在几段文本中查找数字,用正则,很顺利,找到了!也初步理解了“目标文本”和 Match/Matches。但在昨晚家里测试《标题2》时,发现速度有问题了。我想,可能与格式设置很详细有关吧!?因为找到正则匹配结果还不够,还要进一步设置它们的具体格式(字体、缩进等)。刚才我发现网页上有说,杜先生 查找标题2时用的是“选择”法,四种模式同时查找,这可能比只匹配一种模式费时间。

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-20 09:42 | 显示全部楼层
  1. Sub Word2003VBA正则表达式_demo_标准写法()
  2. '费时=.015',快于i.range法=.046'!不要设置变量 m/n 会变慢!)
  3.     Dim RegEx As Object, Match As Object, Matches As Object
  4.     Set RegEx = CreateObject("VBScript.RegExp")
  5.     With RegEx
  6.         .Global = True
  7.         .IgnoreCase = True
  8.         .MultiLine = True
  9.         .Pattern = "\d+"
  10.         Set Matches = .Execute(ActiveDocument.Content)
  11.     End With
  12.     With ActiveDocument
  13.         For Each Match In Matches
  14.             .Range(Start:=Match.FirstIndex, End:=Match.FirstIndex + Match.Length).Font.Color = wdColorRed
  15.         Next
  16.     End With
  17.     Set RegEx = Nothing
  18.     Set Matches = Nothing

  19. '        Set sms = m.SubMatches
  20. '        For i = 0 To sms.Count - 1
  21. '            MsgBox sms.Item(i)
  22. '        Next i
  23. '        Set sms = Nothing
  24. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-20 09:43 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
  1. Sub Word2003VBA正则表达式_demo_简化写法()
  2. '费时=.015',快于i.range法=.046'!不要设置变量 m/n 会变慢!)
  3.     Dim Match As Object, Matches As Object
  4.     With CreateObject("VBScript.RegExp")
  5.         .Global = True
  6.         .IgnoreCase = True
  7.         .MultiLine = True
  8.         .Pattern = "\d+"
  9.         For Each Match In .Execute(ActiveDocument.Content)
  10.             ActiveDocument.Range(Start:=Match.FirstIndex, End:=Match.FirstIndex + Match.Length).Font.Color = wdColorRed
  11.         Next
  12.     End With
  13. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-20 09:44 | 显示全部楼层
  1. Sub Title2345()
  2. '更新/启用正则/杜先生 原代码----测试稍慢!
  3.     Dim doc As Document, mt As Object, i&, s$, x$, b$, c$, d$, e$
  4.     Set doc = ActiveDocument
  5.     s = Replace(doc.Content, Chr(7), "")
  6.     x = "一二三四五六七八九十百零〇○Oo千"
  7.     b = "^[" & x & "]+、"
  8.     c = "^[((]\s*[" & x & "]+\s*[))]"
  9.     d = "^\d+[、..]"
  10.     e = "^[((]\s*\d+\s*[))]"
  11.     With CreateObject("VBScript.RegExp")
  12.         .Global = True
  13.         .MultiLine = True
  14.         .Pattern = "" & c & "|" & b & "|" & e & "|" & d & ""
  15.         For Each mt In .Execute(s)
  16.             With doc.Range(mt.FirstIndex, mt.FirstIndex + mt.Length)
  17.                 If Not .Information(12) Then
  18.                     .Expand 4
  19.                     i = Len(.Text)
  20.                     .Collapse
  21.                     If .MoveWhile(x, i) > 0 Then
  22.                         .Expand 4
  23.                         .Style = wdStyleHeading2
  24.                         .Font.Color = wdColorRed
  25.                     ElseIf .MoveWhile("((", i) > 0 Then
  26.                         If .MoveWhile(x, i) > 0 Then
  27.                             .Expand 4
  28.                             .Style = wdStyleHeading3
  29.                             .Font.NameFarEast = "楷体"
  30.                             .Font.Color = wdColorPink
  31.                         Else
  32.                             .Expand 4
  33.                             .Style = wdStyleHeading5
  34.                             With .Font
  35.                                 .Name = "仿宋"
  36.                                 .Size = 16
  37.                                 .Color = wdColorOrange
  38.                             End With
  39.                         End If
  40.                     Else
  41.                         .Expand 4
  42.                         .Style = wdStyleHeading4
  43.                         With .Font
  44.                             .Name = "仿宋"
  45.                             .Size = 16
  46.                             .Color = wdColorGreen
  47.                         End With
  48.                     End If
  49. '                    MsgBox .Text
  50.                     If .Text Like "*[::]??*" Then
  51. '                        If .Text Like "*:*" Then .Characters(InStr(.Text, ":")).Select: .Range.CharacterWidth = wdWidthFullWidth: .Move 1, 1
  52.                         With doc.Range(Start:=.Characters(InStr(.Text, ":") + 1).Start, End:=.Paragraphs(1).Range.End).Font
  53.                             .Name = "仿宋"
  54.                             .Bold = False
  55.                             .Color = wdColorBlue
  56.                         End With
  57.                     Else
  58.                         If .Sentences.Count = 1 Then
  59.                             If .Text Like "*[。:;,、!?…—.:;,!?]?" Then .Characters.Last.Previous.Delete
  60.                         Else
  61.                             With doc.Range(Start:=.Sentences(1).End, End:=.Paragraphs(1).Range.End).Font
  62.                                 .Name = "仿宋"
  63.                                 .Bold = False
  64.                                 .Color = wdColorBlue
  65.                             End With
  66.                         End If
  67.                     End If
  68.                     With .ParagraphFormat
  69.                         .SpaceBeforeAuto = False
  70.                         .SpaceAfterAuto = False
  71.                         .SpaceBefore = 0
  72.                         .SpaceAfter = 0
  73.                         .LineSpacing = LinesToPoints(1.5)
  74.                         .CharacterUnitFirstLineIndent = 2
  75.                         .AutoAdjustRightIndent = False
  76.                         .DisableLineHeightGrid = True
  77.                         .KeepWithNext = False
  78.                         .KeepTogether = False
  79.                     End With
  80.                     If .Style = "标题 2" Then
  81.                         With .ParagraphFormat
  82.                             .SpaceBefore = 3
  83.                             .SpaceAfter = 3
  84.                         End With
  85.                     End If
  86.                 End If
  87.             End With
  88.         Next
  89.     End With
  90. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-20 09:45 | 显示全部楼层
  1. Sub Title2345()
  2. '未用正则表达式,自编代码,稍快于 正则!
  3.     Dim doc As Document, i&, s$
  4.     Set doc = ActiveDocument
  5.     For i = 1 To 4
  6.         If i = 1 Then
  7.             s = "^13[一二三四五六七八九十百零〇○Oo千]@、*^13"
  8.         ElseIf i = 2 Then
  9.             s = "^13([一二三四五六七八九十百零〇○Oo千]@)*^13"
  10.         ElseIf i = 3 Then
  11.             s = "^13[0-9]@.*^13"
  12.         ElseIf i = 4 Then
  13.             s = "^13([0-9]@)*^13"
  14.         End If
  15.         With Selection
  16.             .HomeKey unit:=wdStory
  17.             With .Find
  18.                 .ClearFormatting
  19.                 Do While .Execute(s, , , 1, , , 1)
  20.                     With .Parent
  21.                         .MoveStart 1, 1
  22.                         If Not .Information(12) Then
  23.                             If .Paragraphs.Count = 1 Then
  24.                                 If i = 1 Then
  25.                                     .Style = wdStyleHeading2
  26.                                     .Font.Color = wdColorRed
  27.                                 ElseIf i = 2 Then
  28.                                     .Style = wdStyleHeading3
  29.                                     .Font.NameFarEast = "楷体"
  30.                                     .Font.Color = wdColorPink
  31.                                 ElseIf i = 3 Then
  32.                                     .Style = wdStyleHeading4
  33.                                     With .Font
  34.                                         .Name = "仿宋"
  35.                                         .Size = 16
  36.                                         .Color = wdColorGreen
  37.                                     End With
  38.                                 ElseIf i = 4 Then
  39.                                     .Style = wdStyleHeading5
  40.                                     With .Font
  41.                                         .Name = "仿宋"
  42.                                         .Size = 16
  43.                                         .Color = wdColorOrange
  44.                                     End With
  45.                                 End If
  46.                                 If .Text Like "*[::]??*" Then
  47.                                     If .Text Like "*:*" Then .Characters(InStr(.Text, ":")).Select: .Range.CharacterWidth = wdWidthFullWidth: .Move 1, 1
  48.                                     With doc.Range(Start:=.Characters(InStr(.Text, ":") + 1).Start, End:=.Paragraphs(1).Range.End).Font
  49.                                         .Name = "仿宋"
  50.                                         .Bold = False
  51.                                         .Color = wdColorBlue
  52.                                     End With
  53.                                 Else
  54.                                     If .Sentences.Count = 1 Then
  55.                                         If .Text Like "*[。:;,、!?…—.:;,!?]?" Then .Characters.Last.Previous.Delete
  56.                                     Else
  57.                                         With doc.Range(Start:=.Sentences(1).End, End:=.Paragraphs(1).Range.End).Font
  58.                                             .Name = "仿宋"
  59.                                             .Bold = False
  60.                                             .Color = wdColorBlue
  61.                                         End With
  62.                                     End If
  63.                                 End If
  64.                                 With .ParagraphFormat
  65.                                     .SpaceBeforeAuto = False
  66.                                     .SpaceAfterAuto = False
  67.                                     .SpaceBefore = 0
  68.                                     .SpaceAfter = 0
  69.                                     .LineSpacing = LinesToPoints(1.5)
  70.                                     .CharacterUnitFirstLineIndent = 2
  71.                                     .AutoAdjustRightIndent = False
  72.                                     .DisableLineHeightGrid = True
  73.                                     .KeepWithNext = False
  74.                                     .KeepTogether = False
  75.                                 End With
  76.                                 If .Style = "标题 2" Then
  77.                                     With .ParagraphFormat
  78.                                         .SpaceBefore = 3
  79.                                         .SpaceAfter = 3
  80.                                     End With
  81.                                 End If
  82.                             End If
  83.                         Else
  84.                             .Tables(1).Range.Next.Select
  85.                         End If
  86.                         .EndKey unit:=wdLine
  87.                     End With
  88.                 Loop
  89.             End With
  90.         End With
  91.     Next i
  92. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-20 09:47 | 显示全部楼层
删除全文域只用一句代码:ActiveDocument.fields.unlink

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-6-20 10:48 | 显示全部楼层
成功!——公文标题四个层次,不要一起处理,要分别查找处理,这样就快了!
费时对比:Title2345my宏=.80秒(传统VBA查找)------Title2345RegExp(宏)=.53秒(正则表达式,分别查找公文标题四个层次)
具体代码如下:
  1. Sub Title2345RegExp()
  2.     Dim doc As Document, i&, s$, t$
  3.     Dim RegEx As Object, Match As Object, Matches As Object
  4.    
  5.     Set doc = ActiveDocument
  6.     t = Replace(doc.Content, Chr(7), "")

  7.     For i = 1 To 4
  8.         If i = 1 Then
  9.             s = "^[一二三四五六七八九十百零〇○Oo千]+、"
  10.         ElseIf i = 2 Then
  11.             s = "^([一二三四五六七八九十百零〇○Oo千]+)"
  12.         ElseIf i = 3 Then
  13.             s = "^\d+."
  14.         ElseIf i = 4 Then
  15.             s = "^(\d+)"
  16.         End If
  17. '''
  18.         Set RegEx = CreateObject("VBScript.RegExp")
  19.         With RegEx
  20.             .Global = True
  21. '            .IgnoreCase = True
  22.             .MultiLine = True
  23.             .Pattern = s
  24.             Set Matches = .Execute(t)
  25.         End With
  26.         With ActiveDocument
  27.             For Each Match In Matches
  28.                 With .Range(Start:=Match.FirstIndex, End:=Match.FirstIndex + Match.Length)
  29.                     .Expand 4
  30. '                    .Select
  31.                     If Not .Information(12) Then
  32.                         If i = 1 Then
  33.                             .Style = wdStyleHeading2
  34.                             .Font.Color = wdColorRed
  35.                         ElseIf i = 2 Then
  36.                             .Style = wdStyleHeading3
  37.                             .Font.NameFarEast = "楷体"
  38.                             .Font.Color = wdColorPink
  39.                         ElseIf i = 3 Then
  40.                             .Style = wdStyleHeading4
  41.                             With .Font
  42.                                 .Name = "仿宋"
  43.                                 .Size = 16
  44.                                 .Color = wdColorGreen
  45.                             End With
  46.                         ElseIf i = 4 Then
  47.                             .Style = wdStyleHeading5
  48.                             With .Font
  49.                                 .Name = "仿宋"
  50.                                 .Size = 16
  51.                                 .Color = wdColorOrange
  52.                             End With
  53.                         End If
  54.                         If .Text Like "*[::]??*" Then
  55.                             If .Text Like "*:*" Then .Characters(InStr(.Text, ":")).Select: .CharacterWidth = wdWidthFullWidth: .Move 1, 1
  56.                             With doc.Range(Start:=.Characters(InStr(.Text, ":") + 1).Start, End:=.Paragraphs(1).Range.End).Font
  57.                                 .Name = "仿宋"
  58.                                 .Bold = False
  59.                                 .Color = wdColorBlue
  60.                             End With
  61.                         Else
  62.                             If .Sentences.Count = 1 Then
  63. '                                MsgBox .Text
  64.                                 If .Text Like "*[。:;,、!?…—.:;,!?]?" Then .Characters.Last.Previous.Delete
  65.                             Else
  66.                                 With doc.Range(Start:=.Sentences(1).End, End:=.Paragraphs(1).Range.End).Font
  67.                                     .Name = "仿宋"
  68.                                     .Bold = False
  69.                                     .Color = wdColorBlue
  70.                                 End With
  71.                             End If
  72.                         End If
  73.                         With .ParagraphFormat
  74.                             .SpaceBeforeAuto = False
  75.                             .SpaceAfterAuto = False
  76.                             .SpaceBefore = 0
  77.                             .SpaceAfter = 0
  78.                             .LineSpacing = LinesToPoints(1.5)
  79.                             .CharacterUnitFirstLineIndent = 2
  80.                             .AutoAdjustRightIndent = False
  81.                             .DisableLineHeightGrid = True
  82.                             .KeepWithNext = False
  83.                             .KeepTogether = False
  84.                         End With
  85.                         If .Style = "标题 2" Then
  86.                             With .ParagraphFormat
  87.                                 .SpaceBefore = 3
  88.                                 .SpaceAfter = 3
  89.                             End With
  90.                         End If
  91.                     End If
  92.                 End With
  93.             Next
  94.         End With
  95. '        Set RegEx = Nothing
  96. '        Set Matches = Nothing
  97.     Next i
  98. End Sub
复制代码
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-23 12:40 , Processed in 0.042212 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表