3

使用此处发布的解决方案,我希望从 Excel 中的不规则数据列表中提取邮政编码。

以下是我的数据的示例:

加拿大布兰普顿 L6P 2G9

M5B2R3 多伦多

多伦多 M5J 0A6 ON 加拿大

M1H1T7 加拿大

多伦多 M4P1T8 ON 加拿大

MISISUAGABRAMPTON L5M6S6 加拿大

333 Sea Ray Inisfil l4e2y6 ON 加拿大

要调用该函数,我使用以下公式

=RegexExtract(A1,"^(?!.*[DFIOQU])[A-VXY][0-9][A-Z] ?[0-9][A-Z][0-9]$")

但是该功能对我不起作用。我想我需要以某种方式调整我的正则表达式,但我不知道我错过了什么。

4

2 回答 2

4

尝试,

=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)

在此处输入图像描述

于 2018-10-05T03:09:35.857 回答
3

你有2个问题。


首先,表达式——如果你需要提取邮政编码,你不能用^and来锚定你的正则表达式$。第一个表示“匹配必须出现在字符串的开头”,第二个表示“匹配必须出现在字符串的末尾”。这仅在您验证邮政编码时有用,但它显然不能用于从您的示例中提取邮政编码,因为它们都包含邮政编码以外的内容。正则表达式的另一个问题是否定的前瞻断言(?!.*[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
于 2018-10-05T03:04:33.847 回答