gpt4 book ai didi

regex - 即使匹配不需要,VBScript 正则表达式也会填充子匹配

转载 作者:行者123 更新时间:2023-12-02 20:18:12 27 4
gpt4 key购买 nike

我正在尝试复制 Google 日历根据叙述创建约会的方法。我想输入 5pm Happy Hour for 1 hour 并将其解析为最终的 Outlook AppointmentItem。

我认为我的问题是最后有一大块可选文本。因为它是可选的,所以正则表达式会通过,但子匹配不会被填充,因为它不是匹配所必需的。我希望它填充,因为我想使用子匹配作为我的解析引擎。

我在 A 列中有一堆测试用例(在 Excel 中工作,然后将移动到 Outlook),我的代码在右侧列出了子匹配。这是潜在输入的代表性样本

1. 5pmCST Happy Hour for 1 hour
2. 5pm CST Happy Hour for 1 hour
3. 5pm Happy Hour for 1 hour
4. 5 pm Happy Hour for 1 hour
5. 5 pm CST Happy Hour for 1 hour
6. 5 Happy Hour for 1 hour
7. 5 Happy Hour
8. 5pmCST Happy Hour
9. 5pm CST Happy Hour
10. 5pm Happy Hour
11. 5:00CST Happy Hour for 1 hour
12. 5:00 CST Happy Hour for 1 hour

这是运行测试的代码

Sub testest()

Dim RegEx As VBScript_RegExp_55.RegExp
Dim Matches As VBScript_RegExp_55.MatchCollection
Dim Match As VBScript_RegExp_55.Match
Dim rCell As Range
Dim SubMatch As Variant
Dim lCnt As Long
Dim aPattern(1 To 8) As String

Set RegEx = New VBScript_RegExp_55.RegExp
aPattern(1) = "(1?[0-9](:[0-5][0-9])?)" 'time
aPattern(2) = "( ?)" 'optional space
aPattern(3) = "([ap]m)?" 'optional ampm
aPattern(4) = "( ?)" 'optional space
aPattern(5) = "([ECMP][DS]T)?" 'optional time zone
aPattern(6) = "( ?)" 'optional space
aPattern(7) = "(.+?)" 'event description
aPattern(8) = "(( for )([1-2]?[0-9](.[0-9]?[0-9])?)( hours?))?" 'optional duration

RegEx.Pattern = Join(aPattern, vbNullString)
Debug.Print RegEx.Pattern

Sheet1.Range("C1").Resize(1000, 100).ClearContents

For Each rCell In Sheet1.Range("A1").CurrentRegion.Columns(1).Cells
lCnt = 0
rCell.Offset(0, 2).Value = RegEx.test(rCell.Text)
If RegEx.test(rCell.Text) Then
Set Matches = RegEx.Execute(rCell.Text)

For Each Match In Matches
For Each SubMatch In Match.SubMatches
lCnt = lCnt + 1
rCell.Offset(0, 2 + lCnt).Value = SubMatch
Next SubMatch
Next Match
End If
Next rCell

End Sub

模式是

(1?[0-9](:[0-5][0-9])?)( ?)([ap]m)?( ?)([ECMP][DS]T)?( ?)(.+?)(( for )([1-2]?[0-9](.[0-9]?[0-9])?)( hours?))?

#1 的子匹配是

1        2          3        4      5       6       7
5 pm CST H

它在欢乐时光中的“H”处停止匹配,因为以“for”开头的所有内容都是可选的。如果我删除可选部分,我的模式就会变成

(1?[0-9](:[0-5][0-9])?)( ?)([ap]m)?( ?)([ECMP][DS]T)?( ?)(.+?)( for )([1-2]?[0-9](.[0-9]?[0-9])?)( hours?)

但是 #7-#10 没有通过,因为它们没有持续时间。 #1 的 submmatches 给了我我想要的东西

1     2     3     4     5     6     7             8     9     10     11
5 pm CST Happy Hour for 1 hour

我希望填充每个可能的子匹配,即使 VBScript 不需要它来使正则表达式通过。我担心这就是它的工作原理,我正在尝试让正则表达式为我完成解析工作。我考虑过通过越来越严格的模式来运行它,直到它不通过,然后使用最后通过的模式,但这看起来很笨拙。

是否可以使用正则表达式来填充这些子匹配?

最佳答案

我假设每一行都是一个单元格中的所有内容。所以我可以使用 anchor 。我也不认为您需要那么多的捕获组。我设置了正则表达式:

Group 1        Time
Group 2 am/pm
Group 3 Time Zone
Group 4 Description
Group 5 Hours (and fractions of hours)

对于 A2:An 中的数据,以下例程将数据解析到相邻列中。子匹配是否“未填充”并不重要。您还可以填充数组中的元素,或者您想做的任何其他事情。如果您想要更多子匹配,您始终可以为可选空间添加捕获组,或将相关的非捕获组更改为捕获组。

此外,由于“for”是可选的,我选择使用前瞻来确定“description”的结尾。描述将以\s+for\s+ 序列结束;或“行尾”。由于我假设每个单元格只有一个条目和一行,因此多行和全局属性是不相关的。

“for”之前和之后必须包含空格,以避免在描述中包含该序列时出现问题。

Option Explicit
'set Reference to Microsoft VBScript Regular Expressions 5.5
Sub ParseAppt()
Dim R As Range, C As Range
Dim RE As RegExp, MC As MatchCollection
Dim I As Long
Set R = Range("a2", Cells(Rows.Count, "A").End(xlUp))
Set RE = New RegExp
With RE
.Pattern = "((?:1[0-2]|0?[1-9])(?::[0-5]\d)?)\s*([ap]m)?\s*([ECMT][DS]T)?\s*(.*?(?=\s+for\s+|$))(?:\s+for\s+(\d+(?:\.\d+)?)\s*hour)?"
.IgnoreCase = True
For Each C In R
If .Test(C.Text) = True Then
Set MC = .Execute(C.Text)
For I = 0 To 4
C.Offset(0, I + 1) = MC(0).SubMatches(I)
Next I
End If
Next C
End With
End Sub

关于regex - 即使匹配不需要,VBScript 正则表达式也会填充子匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21742590/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com