我试图复制Google日历从叙述中创建约会的方法。我想输入“5pm Happy Hour for 1 hour”并将其解析为最终的Outlook AppointmentItem。
我的问题是,我认为末尾有一大块可选文本。因为它是可选的,所以正则表达式通过了,但子匹配没有被填充,因为它不是匹配的必需部分。我希望它能被填充,因为我想使用子匹配作为我的解析引擎。
我在列A中有许多测试用例(在Excel中工作,然后将其移动到Outlook),我的代码列出了右侧的子匹配。这是潜在输入的代表性样本。
以下是运行测试的代码:
这个模式是:
#1的子匹配项为:
我希望每个可能的子匹配都能填充,即使VBScript不需要它也能使正则表达式通过。我担心这就是它的工作原理,而我正在试图让正则表达式为我完成解析工作。我考虑运行它通过越来越严格的模式,直到它无法通过,然后使用最后一个通过的模式,但这似乎很笨拙。
是否有可能让正则表达式填充这些子匹配?
我的问题是,我认为末尾有一大块可选文本。因为它是可选的,所以正则表达式通过了,但子匹配没有被填充,因为它不是匹配的必需部分。我希望它能被填充,因为我想使用子匹配作为我的解析引擎。
我在列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
在“Happy Hour”的“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的子匹配符合我的要求。
1 2 3 4 5 6 7 8 9 10 11
5 pm CST Happy Hour for 1 hour
我希望每个可能的子匹配都能填充,即使VBScript不需要它也能使正则表达式通过。我担心这就是它的工作原理,而我正在试图让正则表达式为我完成解析工作。我考虑运行它通过越来越严格的模式,直到它无法通过,然后使用最后一个通过的模式,但这似乎很笨拙。
是否有可能让正则表达式填充这些子匹配?