托拜厄斯的回答似乎是那张票。只是想补充一下,我刚刚意识到量词在字符类中是没有意义的。还注意到一个同事的电子邮件经常在数字前面和美元符号后面有一个空格,所以下面是一些更好的正则表达式(对于美元amts):
RegExp.Pattern = "\$\s*([\,\d]*(?:\.\d{2})?)"
字符串
从中得到一些启发:What does a hyperlink range.start and range.end refer to?得出了这个结论:
Sub trueUpAttempt()
Dim OrigLength As Long
Debug.Print ActiveDocument.Characters.Count
Dim SelStart As Long
Dim SelEnd As Long
Dim SelLength As Long
Dim rHyperlink As Range
Dim wdHyperlink As Hyperlink
For Each wdHyperlink In ActiveDocument.Hyperlinks
Set rHyperlink = wdHyperlink.Range
'Debug.Print rHyperlink.Start
'Debug.Print rHyperlink.End
'Debug.Print rHyperlink.End - rHyperlink.Start
Debug.Print rHyperlink.End - rHyperlink.Start - Len(rHyperlink)
'there's got to be some way to true up the character offset, even if its ugly
Debug.Print ActiveDocument.Characters.Count + rHyperlink.End - rHyperlink.Start - Len(rHyperlink)
Next
End Sub
型
这不是一个修复,但我认为是一个大纲,以协调字符偏移。这完全是因为word计算了所有62个字符,例如{HYPERLINK "http://www.smithany.com"} http://www.smithany.com
编辑2023年7月22日尝试Tobais的建议:
Sub DollarHighlighter2()
Set regExp = New regExp
Dim objMatch As Match
Dim colMatches As MatchCollection
Dim offsetEnd As Long
offsetEnd = Selection.End
regExp.Pattern = "\$([\,\d{1,3}]*(?:\.\d{2})?)"
regExp.Global = True
Set allMatches = regExp.Execute(Selection.text) ' Execute search.
For i = allMatches.Count - 1 To 0 Step -1
'MsgBox allMatches.Item(i)
ActiveDocument.Range(offsetEnd - allMatches.Item(i).FirstIndex, End:=offsetEnd - allMatches.Item(i).FirstIndex + allMatches.Item(i).Length).FormattedText.HighlightColorIndex = wdYellow
Next
End Sub
型
但这似乎仍然有一个类似的问题与链接,也许其他内容。我也尝试了同样的范围确定正向,但在反向循环匹配,并有类似的问题。
示例文件的工作链接(无ssl):http://www.smithany.com/exampleDollarHighliter.docx的
**原文:**我看过其他几篇StackOverflow的文章,比如这篇:How to Use/Enable (RegExp object) Regular Expression using VBA (MACRO) in word在Microsoft Word中使用正则表达式与VBA使用Microsoft VB脚本正则表达式5.5参考。
这帮助我准备了以下内容,我在Word中使用这些内容来突出显示美元金额:
Sub dollarHighlighter()
Set regExp = New regExp
Dim objMatch As Match
Dim colMatches As MatchCollection
Dim offsetStart As Long
offsetStart = Selection.Start
regExp.Pattern = "\$([\,\d{1,3}]*(?:\.\d{2})?)"
regExp.Global = True
Set colMatches = regExp.Execute(Selection.Text) ' Execute search.
For Each objMatch In colMatches ' Iterate Matches collection.
Set myRange = ActiveDocument.Range(objMatch.FirstIndex + offsetStart,
End:=offsetStart + objMatch.FirstIndex + objMatch.Length)
myRange.FormattedText.HighlightColorIndex = wdYellow
Next
End Sub
型
虽然这在文本中的美元金额列表上按预期工作(在大多数情况下- * 在其不完善之处,正则表达式故意有点松散 *),但当Word文档中存在超链接时,它不会按预期工作。
在这种情况下,突出显示的字符的偏移量似乎以某种不可预测的方式发生了偏移。我假设这是因为在document.xml源文件中有很多新的xml/css。
最后,我的首要问题是,我可以使用正则表达式来突出显示word文档内容,即使它包含超链接吗?这是一个偏移量问题,还是我应该在压缩的xml上运行正则表达式,重新压缩并重新打开以获得更好的结果?当我在源代码上测试各种正则表达式变体时,我得到了预期的结果,但在格式化Word范围时却没有。
我在这里也问过:https://social.msdn.microsoft.com/Forums/en-US/3a95c5e4-9e0c-4da9-970f-e0bf801c3170/macro-for-a-regexp-search-replace?forum=isvvba&prof=required但意识到这是一个古老的职位...
下面是一些可能有用的链接:示例文档http://www.smithany.com/test.docx步骤1 http://www.smithany.com/wordusd1.jpg步骤2 http://www.smithany.com/wordhighlighterrun.jpg以及发生的情况http://www.smithany.com/whatactuallyhappens.jpg
**临时解决方法:**如下所示,如果不堆叠循环,Word的通配符查找速度很快。试试这个:
Sub Macro2()
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
Selection.Find.Replacement.highlight = True
With Selection.Find
.Text = "$[0-9,]{1,}"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
End With
Selection.Find.Execute Replace:=wdReplaceAll
Selection.Find.ClearFormatting
Selection.Find.Replacement.ClearFormatting
Selection.Find.Replacement.highlight = True
With Selection.Find
.Text = "$[0-9,]{1,}.[0-9]{2,3}"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = True
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
End With
Selection.Find.Execute Replace:=wdReplaceAll
型
结束子
基本上就是把所有的金额都加亮了也就是说,像匹配各种日期格式这样的复杂表达式可能会变得混乱,但我认为一次一步地完成它们是完全可能的。
2条答案
按热度按时间pobjuy321#
我已经很多年没有接触VBA了,但我想这就像骑自行车一样。
无论如何,这里有一个潜艇,应该可以帮助你。它基于Cindy Meister的声音建议,并使用可选部分的匹配模式集合填补了Regex和Wildcard Find之间差距。
首先,通配符匹配:
$[0-9,]{1,}
和$[0-9,]{1,}.[0-9]{2}
其实也没什么不同,不是吗?然而,为了考虑可选的分数部分,我必须使用两种模式。
这是程序
字符串
如果需要的话,应该很容易扩展或修改这种方法。
这highlithts美元数额所需的在我的结束:
x1c 0d1x的数据
注意:量词{n
,
m}中的分隔符在所有本地化中并不相同,例如在德语版本中是{n;
m}。z9smfwbn2#
**更新26.07.2023:**如果你逐段浏览你的文档,你可以很容易地绕过所有这些问题。但是,这在您的情况下是有效的,因为正则表达式匹配保持在段落边界内!
考虑到这个限制,下面的vba代码将工作:
字符串
@Allan:应该使用YourVariable.SetRange,这样可以根据字符位置定义范围。
这应该可以工作:
型
昨天(2017年7月20日),我遇到了同样的问题:基于正则表达式模式识别文本出现-并将其转换为超链接。
对我有用的是:逆向求解!
regex对象一旦为“SET”,就具有基于原始单词文本的静态索引值。通过插入超链接,文字变得更长。因此,要么在每个文本操作之后重新定义regex对象(问题:如果所插入的超链接本身将获得匹配...)。或者从头到尾解析文档。这可以通过倒计时循环来完成,从最后一个regex出现开始。