Caf*_*der 6 regex arrays excel vba excel-vba
我有一个非常多余的旧代码,我在第一次发现并决定学习vba时创建了这个代码(而且我有很长的路要走).我正在使用此代码循环遍历包含用逗号分隔的多个值的单元格.但是,有些情况下我不能简单地使用诸如Split(string,",")
函数之类的东西,因为某些值在该值中有逗号(示例值:[blah blah,so blah blah]).在存在这些括号的情况下(它们围绕着其中包含逗号的每个值)我设计了相当啰嗦的方法,这是我的旧方法,正确地将值拆分,将它们转储到数组中,然后继续我的其他任务.但是,现在我决定重新审视代码并修复准确性.这是一些背景知识.
可以在一个单元格中找到的示例数据:
请注意:这是供应商发送给我们的数据,我们无法控制他们输入的内容或输入方式.这是一个简单的示例,用于说明在某些情况下通常如何提供数据的要点
Available on 2 sides: Silkscreen,[full: color, covers entire face],Pad Print: One color,[heat transfer, may bleed]
Run Code Online (Sandbox Code Playgroud)
价值观是:
我在寻找:
我正在寻找一种更有效,更简单的方法,能够正确地分割值(同时保持括号中的值).
我相信我已经设法使用以下代码创建一个更有效和紧凑的方法来处理不包括括号的实例
新规范(正在建设中): 我遇到的问题是不知道如何使用括号高效准确地拆分单元格
Sub Test()
Dim rngXid As Range, RegularColons As New Collection, UpchargeColons As New Collection, additionals As Range, upcharges As Range, Colon, UpchargeColon
Dim Values() As String, endRange As Long, xidMap As Object, xid As String, NumberofValues As Integer
endRange = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
Set xidMap = getXidMap(ActiveSheet.Range("A2:A" & UsedRange.Rows.Count)) 'Map products for quicker navigation
Set additionals = ActiveSheet.Range("AJ:AK"): Set upcharges = ActiveSheet.Range("CS:CT")
Set RegularColons = FindAllMatches(additionals, ":") 'This returns all instances/cells that contain a colon in the specified columns
If Not RegularColons Is Nothing Then
For Each Colon In RegularColons
xid = ActiveSheet.Range("A" & Colon.Row).Value
If InStr(1, Colon.Value, "[") = 0 Then 'If no brackets then simply split
Values = Split(Trim(Colon.Value), ",")
Else
'This is where I'm at a lose for a more effective method
'-----------Populate Values array with Colon.Value while watching out for brackets--------
End If
Set rngXid = xidMap(xid).EntireRow.Columns(upcharges) 'set to this specific product
For ColorLocation = LBound(Values) To UBound(Values) 'cycle through each value in Values array
If Not InStr(1, Values(ColorLocation), ":") = 0 Then 'Only proceed if the value has a colon
Set UpchargeColons = FindAllMatches(rngXid, Values(ColorLocation)) 'Searching other columns for this value
If Not UpchargeColons Is Nothing Then
For Each UpchargeColon In UpchargeColons 'If found in other columns proceed to replace colon
UpchargeColon.Value = Replace(UpchargeColon.Value, ":", " ")
Log UpchargeColon.Range, "Removed Colon from Additional Color/Location Upcharge", "Corrected" 'This is a custom sub of mine to record the change
Next UpchargeColon
End If
Values(ColorLocation) = Replace(Values(ColorLocation), ":", " ")
End If
Next ColorLocation
Log Colon.Range, "Removed Colon(s) from Additional Color/Location Value(s)", "Corrected"
Next Colon
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
我一直在寻找可能的方法来做到这一点,并且一直坚持不懈的是Regex
,尽管我之前已经听说过,但我确实没有经验.所以,我想它阅读了使用类似的网站了一下这个,当然还有MSDN文档.我在尝试更多地了解这种方法时的观察/想法是:
所以,我的问题是:
在包含括号的单元格中准确分割值的最有效方法是什么?
正则表达式(又名“regex”)确实看起来很吓人,但它们也是一个强大的工具,如果您添加对Microsoft VBScript 正则表达式 5.5库的引用,VBA 也支持它们。
使用它,您可以创建一个RegExp
对象,它为您提供一个MatchCollection
,它是一个对象的集合Match
。
以下是如何使用它们:
Sub Test()
Const value As String = _
"Available on 2 sides: Silkscreen,[full: color, covers entire face],Pad Print: One color,[heat transfer, may bleed]"
Const pattern As String = _
"(\[[^\]]+\]|[^,]+)"
Dim regex As New RegExp
regex.Global = True
regex.pattern = pattern
Dim matches As MatchCollection
Set matches = regex.Execute(value)
Dim m As Match
For Each m In matches
Debug.Print Trim(m.value) 'value will preserve any leading/trailing spaces
Next
End Sub
Run Code Online (Sandbox Code Playgroud)
请注意,劳雷尔的回答pattern
几乎就是这样:
(\[[^\]]+\]|[^,]+)
Run Code Online (Sandbox Code Playgroud)
通过不指定您想要匹配逗号,您就不会匹配它(无论它是否存在) - 因此,上面的代码输出如下:
Sub Test()
Const value As String = _
"Available on 2 sides: Silkscreen,[full: color, covers entire face],Pad Print: One color,[heat transfer, may bleed]"
Const pattern As String = _
"(\[[^\]]+\]|[^,]+)"
Dim regex As New RegExp
regex.Global = True
regex.pattern = pattern
Dim matches As MatchCollection
Set matches = regex.Execute(value)
Dim m As Match
For Each m In matches
Debug.Print Trim(m.value) 'value will preserve any leading/trailing spaces
Next
End Sub
Run Code Online (Sandbox Code Playgroud)
MatchCollection
如果需要,您可以轻松地迭代 a来填充数组。