使用发布于here的解决方案,我希望从Excel中的不规则数据列表中提取邮政编码。
以下是我的数据的示例:
Brampton L6P 2G9在加拿大上
M5B2R3多伦多开启
加拿大多伦多多伦多M5J 0A6
M1H1T7加拿大
加拿大的多伦多M4P1T8
加拿大的MISSISUAGABRAMPTON L5M6S6
加拿大境内的333 Sea Ray Inisfil l4e2y6
要调用该函数,我使用以下公式
=RegexExtract(A1,"^(?!.*[DFIOQU])[A-VXY][0-9][A-Z] ?[0-9][A-Z][0-9]$")
但是该功能不适用于我。我想我需要以某种方式调整我的正则表达式,但是我不知道我缺少什么。
答案 0 :(得分:3)
您有2期。
首先,表达式-如果需要提取邮政编码,则不能使用^
和$
锚定正则表达式。第一种表示“匹配必须在字符串的开头发生”,第二种表示“匹配必须在字符串的结尾结束”。这仅在验证邮政编码时有用,但显然不能用于从示例中提取邮政编码,因为它们都包含邮政编码以外的内容。
正则表达式的另一个问题是否定的前瞻性断言(?!.*[DFIOQU])
,这意味着“没有匹配项可以包含字母D,F,I,O,Q或U”。据我所知,VBScript正则表达式不支持此功能。如果我弄错了,请在评论中纠正我。
这会给您带来一些古怪的表情:
[ABCEGHJKLMNPRSTVX]\d[ABCEGHJKLMNPRSTVWXYZ][ -]?\d[ABCEGHJKLMNPRSTVWXYZ]\d
我自由选择在FSA和LDU之间允许使用-
,因为我看到有很多 ,尤其是来自非加拿大人的。
第二,您正在调用的函数(从链接的答案中复制过来):
Function RegexExtract(ByVal text As String, _ ByVal extract_what As String, _ Optional separator As String = ", ") As String Dim allMatches As Object Dim RE As Object Set RE = CreateObject("vbscript.regexp") Dim i As Long, j As Long Dim result As String RE.pattern = extract_what RE.Global = True Set allMatches = RE.Execute(text) For i = 0 To allMatches.count - 1 For j = 0 To allMatches.Item(i).submatches.count - 1 result = result & (separator & allMatches.Item(i).submatches.Item(j)) Next Next If Len(result) <> 0 Then result = Right$(result, Len(result) - Len(separator)) End If RegexExtract = result End Function
第一个问题是它区分大小写。它还专门用于提取您不关心的子匹配-您的示例正在寻找单个匹配。
我会使用这个更简单的选项,该选项也可以正确格式化输出:
Public Function ExtractCanadianPostalCode(inputText As String) As String
With CreateObject("vbscript.regexp")
.Pattern = "[ABCEGHJKLMNPRSTVX]\d[ABCEGHJKLMNPRSTVWXYZ][ -]?\d[ABCEGHJKLMNPRSTVWXYZ]\d"
.IgnoreCase = True
If .Test(inputText) Then
Dim matches As Object
Set matches = .Execute(inputText)
ExtractCanadianPostalCode = UCase$(Left$(matches(0), 3) & " " & Right$(matches(0), 3))
End If
End With
End Function
答案 1 :(得分:3)
尝试
=REGEXEXTRACT(upper(A2), "[A-X]\d[A-Z] ?\d[A-Z]\d")
'alternate
=left(REGEXEXTRACT(upper(A2), "[A-X]\d[A-Z] ?\d[A-Z]\d"), 3)&" "&right(REGEXEXTRACT(upper(A2), "[A-X]\d[A-Z] ?\d[A-Z]\d"), 3)