用于识别英国邮政编码的 R 正则表达式

Posted

技术标签:

【中文标题】用于识别英国邮政编码的 R 正则表达式【英文标题】:R Regex for identifying UK postcodes 【发布时间】:2018-04-25 11:50:31 【问题描述】:

我的问题类似于this,但我正在寻找特定于R 的内容。我有一个包含数万个地址的data.frame,需要提取邮政编码。邮政编码位于英国,格式为 LETTER_LETTER_DIGIT LETTER_LETTER_DIGIT。类似于以下内容:

“8,Longbow Close,\r\nHarlescott Lane,\r\nShrewsbury,\r\n英格兰,\r\nSY1 3GZ”

我用stringr 使用了这段代码的变体,但无济于事:

str_extract('^(\\[Gg]\\[Ii]\\[Rr] 0\\[Aa]2)|(((\\[A-Za-z]\\[0-9]1,2)|((\\ 
[A-Za-z]\\[A-Ha-hJ-Yj-y]\\[0-9]1,2)|((\\[AZa-z]\\[0-9]\\[A-Za-z])|(\\[A-Za- 
z]\\[A-Ha-hJ-Yj-y]\\[0-9]?\\[A-Za-z]))))\\[0-9]\\[A-Za-z]2)$',alfa$Address) 

【问题讨论】:

为什么没有用?发生了什么?我猜你因为^$ 而没有匹配到。删除它们或替换为\\b,并使用str_extract_all。并交换参数,第一个是输入,第二个是正则表达式。并且不要转义[,这是一个字符类的开始。 为什么会有双反斜杠? @WiktorStribiżew,我首先得到了 NA。删除^$ 并使用str_extract_all 后,我得到character(0) 因为所有[ 都匹配为文字[。删除逃逸。您为什么更改链接到的帖子中的正则表达式? 【参考方案1】:

^$ 锚点要求模式匹配整个字符串。您可以使用 \b(?:<pattern>)\b 包装模式以匹配这些代码作为整个单词(\b 是单词边界)。此外,字符类被“破坏”,因为您转义了它们的 [ 起始括号(\[ 匹配文字 [ 字符)。另外,交换参数,第一个是输入,第二个是正则表达式。此外,要获得所有匹配项,您需要使用str_extract_all 而不是str_extract

您可以像这样修复代码:

library(stringr)
txt <- "8, Longbow Close,\r\nHarlescott Lane,\r\nShrewsbury,\r\nEngland,\r\nSY1 3GZ"
pattern <- "\\b(?:([Gg][Ii][Rr] 0[Aa]2)|((([A-Za-z][0-9]1,2)|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]1,2)|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))\\s?[0-9][A-Za-z]2))\\b"
str_extract_all(txt, pattern)
# => [[1]]
#   [1] "SY1 3GZ"

【讨论】:

感谢您的解释。您的代码完美运行!【参考方案2】:

这是一种更易读的方式:

            if ($elocate =~ /\b([A-Z])([A-Z])([0-9])([A-Z]) ([0-9])([A-Z])([A-Z])\b/) 
                    $ezip = $1.$2.$3.$4.$5.$6.$7;
                    $ezips = $1.$2.$3.$4.' ' .$5.$6.$7;
             elsif ($elocate =~ /\b([A-Z])([0-9])([A-Z]) ([0-9])([A-Z])([A-Z])\b/) 
                    $ezip = $1.$2.$3.$4.$5.$6;
                    $ezips = $1.$2.$3.' '.$4.$5.$6;
             elsif ($elocate =~ /\b([A-Z])([0-9]) ([0-9])([A-Z])([A-Z])\b/) 
                    $ezip = $1.$2.$3.$4.$5;
                    $ezips = $1.$2.' '.$3.$4.$5;
             elsif ($elocate =~ /\b([A-Z])([0-9])([0-9]) ([0-9])([A-Z])([A-Z])\b/) 
                    $ezip = $1.$2.$3.$4.$5.$6;
                    $ezips = $1.$2.$3.' '.$4.$5.$6;
             elsif ($elocate =~ /\b([A-Z])([A-Z])([0-9]) ([0-9])([A-Z])([A-Z])\b/) 
                    $ezip = $1.$2.$3.$4.$5.$6;
                    $ezips = $1.$2.$3.' ' .$4.$5.$6;
             elsif ($elocate =~ /\b([A-Z])([A-Z])([0-9])([0-9]) ([0-9])([A-Z])([A-Z])\b/) 
                    $ezip = $1.$2.$3.$4.$5.$6.$7;
                    $ezips = $1.$2.$3.$4.' '.$5.$6.$7;
            

【讨论】:

以上是关于用于识别英国邮政编码的 R 正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

C# - 英国邮政编码正则表达式没有按预期工作?

英国邮政编码正则表达式验证

使用正则表达式验证英国邮政编码

正则表达式匹配英国邮政编码的前半部分

英国邮政编码的正则表达式

带空格的英国邮政编码正则表达式