使用 RegEx 匹配 Excel/VBA 中的五个字符,第一个字符取决于单元格值
Matching five characters in Excel/VBA using RegEx, with first character being dependant on cell value
我需要你的帮助!我想在 Excel/VBA 环境中使用 RegEx。我确实有一个方法,但我有点达到我的极限...
我需要匹配很多行字符串中的 5 个字符(字符串在我的 excel sheet 的 B 列中,A 稍后出现)。 5 个字符可以是 5 位数字或“K”后跟 4 位数字(例如 12345
、98765
、K2345
)。这将由 (\d{5}|K\d{4})
.
涵盖
这五个可以前后跟字母或特殊字符,但不能跟数字。这意味着不允许有前导零,而且数字不应该只在更长的数字中匹配。这是我卡住的一点。
如果字符串中有多个可能的匹配项,我需要将它们全部匹配。如果同一个数字已经在一行中被匹配,我希望它不再被匹配。对于这两个要求,我确实已经有了一种解决方案,作为本文末尾 VBA 代码的一部分:(\d{5}|K\d{4})(?!.*?.*$)
此外,我在 A 列中确实有一个特定的单个数字(或“K”)。我需要五个字符以这个特定字符开头,否则将无法匹配。
字符串示例(编号)。 A、B两列用“|”分隔为了更好的可读性
(1) | 1 | 2018/ID11298 00000012345 PersoNR: 889899 Bridgestone BNPN
(2) | 3 | Kompo 32280EP ###Baukasten### 3789936690 ID PFK Carbon0
(3) | 2 | 20613, 20614, Mietop Antragsnummer C300Coup IVS 33221 ABF
(4) | 2 | Q21009 China lokal produzierte Derivate f/Radverbund 991222 VV
(5) | 6 | ID:61953 F-Pace Enfantillages (Machine arriere) VvSKPMG Lyon09
(6) | 2 | 2017/22222 22222 21895 Einzelkostenprob. 28932 ZürichMP KOS
(7) | K | ID:K1245 Panamera Nitsche Radlager Derivativ Bayreumion PwC
(8) | 7 | LaunchSupport QBremsen BBG BFG BBD 70142,70119 KK 70142
我在这里寻找的结果是:
(1) | 11298 | ............................. [but don't match 12345, since no preceeding numbers allowed]
(2) | 32280 | ............................. [but don't match 37899 within 3789936690]
(3) | 20613 | 20614 | ................ [match both starting with a 2, don't match the one starting with 3]
(4) | 21009 | ............................. [preceeded by a letter, which is perfectly fine
(5) | 61953 | ..............................[random example]
(6) | 22222 | 21895 | 28932 | ... [match them all, but no duplicates]
(7) | K1245 | ............................. [special case with a "K"]
(8) | 70142 | 70119 | ................ [ignore second 70142]
到目前为止我整理的 RegEx/VBA 代码是:
Sub RegEx()
Dim varOut() As Variant
Dim objRegEx As Object
Dim lngColumn As Long
Dim objRegA As Object
Dim varArr As Variant
Dim lngUArr As Long
Dim lngTMP As Long
On Error GoTo Fin
With Worksheets("Sheet1")
varArr = .Range("B2:B50")
Set objRegEx = CreateObject("VBScript.Regexp")
With objRegEx
.Pattern = "(\d{5}|K\d{4})(?!.*?.*$)" 'this is where the magic happens
.Global = True
For lngUArr = 1 To UBound(varArr)
Set objRegA = .Execute(varArr(lngUArr, 1))
If objRegA.Count >= lngColumn Then
lngColumn = objRegA.Count
End If
Set objRegA = Nothing
Next lngUArr
If lngColumn = 0 Then Exit Sub
ReDim varOut(1 To UBound(varArr), 1 To lngColumn)
For lngUArr = 1 To UBound(varArr)
Set objRegA = .Execute(varArr(lngUArr, 1))
For lngTMP = 1 To objRegA.Count
varOut(lngUArr, lngTMP) = objRegA(lngTMP - 1)
Next lngTMP
Set objRegA = Nothing
Next lngUArr
End With
.Cells(2, 3).Resize(UBound(varOut), UBound(varOut, 2)) = varOut
End With
Fin:
Set objRegA = Nothing
Set objRegEx = Nothing
If Err.Number <> 0 Then MsgBox "Error: " & Err.Number & " " & Err.Description
End Sub
此代码正在检查 B 列中的字符串,并在 C、D、E 等列中提供匹配项。它不匹配重复项。然而,它是在更大的数字中匹配数字,这是一个问题。例如 \b
对我不起作用,因为我仍然想在 EP12345
.
中匹配 12345
此外,我不知道如何将 A 列中的字符设置为第一个字符。
我已经在此处上传了我的 excel 文件:mollmell.de/RegEx.xlsm
非常感谢您的建议
斯蒂芬
要对太长的数字进行排序,您可以使用不匹配前后数字的负后视和前视:
(?x) (?<!\d) (\d{5} | K\d{4}) (?!\d)
https://regex101.com/r/RBnoMo/1
只匹配数字与第 2 列中的键是相当困难的。也许您匹配了键或数字,然后再执行逻辑:
(?x)
\|[ ](?<key>.)[ ]\| |
(?<!\d) (?<number>\d{5} | K\d{4}) (?!\d)
我需要你的帮助!我想在 Excel/VBA 环境中使用 RegEx。我确实有一个方法,但我有点达到我的极限...
我需要匹配很多行字符串中的 5 个字符(字符串在我的 excel sheet 的 B 列中,A 稍后出现)。 5 个字符可以是 5 位数字或“K”后跟 4 位数字(例如 12345
、98765
、K2345
)。这将由 (\d{5}|K\d{4})
.
这五个可以前后跟字母或特殊字符,但不能跟数字。这意味着不允许有前导零,而且数字不应该只在更长的数字中匹配。这是我卡住的一点。
如果字符串中有多个可能的匹配项,我需要将它们全部匹配。如果同一个数字已经在一行中被匹配,我希望它不再被匹配。对于这两个要求,我确实已经有了一种解决方案,作为本文末尾 VBA 代码的一部分:(\d{5}|K\d{4})(?!.*?.*$)
此外,我在 A 列中确实有一个特定的单个数字(或“K”)。我需要五个字符以这个特定字符开头,否则将无法匹配。
字符串示例(编号)。 A、B两列用“|”分隔为了更好的可读性
(1) | 1 | 2018/ID11298 00000012345 PersoNR: 889899 Bridgestone BNPN
(2) | 3 | Kompo 32280EP ###Baukasten### 3789936690 ID PFK Carbon0
(3) | 2 | 20613, 20614, Mietop Antragsnummer C300Coup IVS 33221 ABF
(4) | 2 | Q21009 China lokal produzierte Derivate f/Radverbund 991222 VV
(5) | 6 | ID:61953 F-Pace Enfantillages (Machine arriere) VvSKPMG Lyon09
(6) | 2 | 2017/22222 22222 21895 Einzelkostenprob. 28932 ZürichMP KOS
(7) | K | ID:K1245 Panamera Nitsche Radlager Derivativ Bayreumion PwC
(8) | 7 | LaunchSupport QBremsen BBG BFG BBD 70142,70119 KK 70142
我在这里寻找的结果是:
(1) | 11298 | ............................. [but don't match 12345, since no preceeding numbers allowed]
(2) | 32280 | ............................. [but don't match 37899 within 3789936690]
(3) | 20613 | 20614 | ................ [match both starting with a 2, don't match the one starting with 3]
(4) | 21009 | ............................. [preceeded by a letter, which is perfectly fine
(5) | 61953 | ..............................[random example]
(6) | 22222 | 21895 | 28932 | ... [match them all, but no duplicates]
(7) | K1245 | ............................. [special case with a "K"]
(8) | 70142 | 70119 | ................ [ignore second 70142]
到目前为止我整理的 RegEx/VBA 代码是:
Sub RegEx()
Dim varOut() As Variant
Dim objRegEx As Object
Dim lngColumn As Long
Dim objRegA As Object
Dim varArr As Variant
Dim lngUArr As Long
Dim lngTMP As Long
On Error GoTo Fin
With Worksheets("Sheet1")
varArr = .Range("B2:B50")
Set objRegEx = CreateObject("VBScript.Regexp")
With objRegEx
.Pattern = "(\d{5}|K\d{4})(?!.*?.*$)" 'this is where the magic happens
.Global = True
For lngUArr = 1 To UBound(varArr)
Set objRegA = .Execute(varArr(lngUArr, 1))
If objRegA.Count >= lngColumn Then
lngColumn = objRegA.Count
End If
Set objRegA = Nothing
Next lngUArr
If lngColumn = 0 Then Exit Sub
ReDim varOut(1 To UBound(varArr), 1 To lngColumn)
For lngUArr = 1 To UBound(varArr)
Set objRegA = .Execute(varArr(lngUArr, 1))
For lngTMP = 1 To objRegA.Count
varOut(lngUArr, lngTMP) = objRegA(lngTMP - 1)
Next lngTMP
Set objRegA = Nothing
Next lngUArr
End With
.Cells(2, 3).Resize(UBound(varOut), UBound(varOut, 2)) = varOut
End With
Fin:
Set objRegA = Nothing
Set objRegEx = Nothing
If Err.Number <> 0 Then MsgBox "Error: " & Err.Number & " " & Err.Description
End Sub
此代码正在检查 B 列中的字符串,并在 C、D、E 等列中提供匹配项。它不匹配重复项。然而,它是在更大的数字中匹配数字,这是一个问题。例如 \b
对我不起作用,因为我仍然想在 EP12345
.
12345
此外,我不知道如何将 A 列中的字符设置为第一个字符。
我已经在此处上传了我的 excel 文件:mollmell.de/RegEx.xlsm
非常感谢您的建议
斯蒂芬
要对太长的数字进行排序,您可以使用不匹配前后数字的负后视和前视:
(?x) (?<!\d) (\d{5} | K\d{4}) (?!\d)
https://regex101.com/r/RBnoMo/1
只匹配数字与第 2 列中的键是相当困难的。也许您匹配了键或数字,然后再执行逻辑:
(?x)
\|[ ](?<key>.)[ ]\| |
(?<!\d) (?<number>\d{5} | K\d{4}) (?!\d)