从字符串中删除美国邮政编码:R regex
我正在尝试从字符串中删除/提取邮政编码。逻辑是我抓住的东西是:从字符串中删除美国邮政编码:R regex,regex,r,Regex,R,我正在尝试从字符串中删除/提取邮政编码。逻辑是我抓住的东西是: 必须正好包含5个连续数字或 必须正好包含5个连续数字,后跟破折号,然后正好包含4个连续数字或 必须正好包含5个连续数字,后跟空格,然后正好包含4个连续数字 字符串的zip部分可以以空格开头,但不能以空格开头 这是一个MWE和我试过的。尝试的两个正则表达式基于和: 注意R的正则表达式与其他正则表达式类似,但特定于R。此问题特定于R的正则表达式,而不是一般的正则表达式问题。您可以使用如下正则表达式: "(?<!\\d)(\\d{5
注意R的正则表达式与其他正则表达式类似,但特定于R。此问题特定于R的正则表达式,而不是一般的正则表达式问题。您可以使用如下正则表达式:
"(?<!\\d)(\\d{5}(?:[-\\s]\\d{4})?)\\b"
”(?这对我来说很有效,并在您的所有示例中提供了所需的输出:
"(?<!\\d)(\\d{5}(?:[- ]\\d{4})?)(?!\\d)"
(?环视断言
您可以在此处使用和单词边界的组合\b
regmatches(text.var, gregexpr('(?<!\\d)\\d{5}(?:[ -]\\d{4})?\\b', text.var, perl=T))
带LookArounds的正则表达式:
(?
现场演示:
我们想要的东西:
[0-9]{5}
是最重要的部分,精确查找5位数字
(?:[-][0-9]{4})
可选择后跟4个以上,但仅当由空格或减号连接时
边界,边界,边界:
(?第一组:负向后看(确保没有数字或破折号)
(?![0-9-])
最后一组:负前瞻(| |-相同模式…)
额外测试用例:
另一个邮政编码09788-4234后面没有空格
98712
987122
邮编或范围12987-19222?
这个序列号88101-8892-22912-9991-99101怎么样?
90872-8881
为什么?
- LookArounds不使用
字符
- 您不应该检测到误报(例如,从“否”开始的第一个或最后5个数字)
- ZIP可能在它自己的线路上,或者在最开始或最末尾
- 你可能会遇到一个没有空间的地址
- 以减号开头的5位数字不应是邮政编码
最终注释:这不是一个最终的或防弹的匹配代码,您可能仍然会收集一些zip外观,特别是因为您需要的数字组之间有空格
个人提示:我发现[0-9]
字符类对于新加入RegEx的人来说更清晰、更容易理解,即使它们包含在\d
中,但它们也更快,并且在RegEx风格之间有更好的兼容性。另一方面,双转义(例如\\d
是一种难看的读法)qdapRegex
软件包具有rm_zip
功能(基于@hwnd的响应):
rm_zip(text.var)
rm_zip(text.var, extract=TRUE)
> rm_zip(text.var, extract=TRUE)
[[1]]
[1] NA
[[2]]
[1] NA
[[3]]
[1] "12345"
[[4]]
[1] NA
[[5]]
[1] "12345-6789" "12345-6789"
[[6]]
[1] "12345 6789" "12345 6789"
[[7]]
[1] NA
我对这个注释不太清楚。例如,当您使用perl=TRUE
时,您可以使用perl正则表达式,因此一般来说,经典正则表达式是一个R解决方案。@AGR请进一步研究将反斜杠和任何其他特定于R的正则表达式加倍的方法(我对正则表达式不太了解,不知道这些东西是什么,但我发现非R用户的正则表达式通常不能转换为R)。工作正常。谢谢。评论也非常有用!刚刚看到你有一个正则表达式解释工具:非常酷:-)此外,我正在将这些正则表达式转换成一个快速的R包。我想给你一个在包上的贡献者作者身份,名称超出SO的hwnd。如果你想使用你的实际名称,请发送一封电子邮件中需要双转义符R@hwnd实际上,而且[0-9]
绕过了双重转义\d
regmatches(text.var, gregexpr('(?<!\\d)\\d{5}(?:[ -]\\d{4})?\\b', text.var, perl=T))
(?<! # look behind to see if there is not:
\d # digits (0-9)
) # end of look-behind
\d{5} # digits (0-9) (5 times)
(?: # group, but do not capture (optional):
[ -] # any character of: ' ', '-'
\d{4} # digits (0-9) (4 times)
)? # end of grouping
\b # the boundary between a word character (\w) and not a word character
> library(stringi)
> stri_extract_all_regex(text.var, '(?<!\\d)\\d{5}(?:[ -]\\d{4})?\\b')
(?<![0-9-])([0-9]{5}(?:[ -][0-9]{4})?)(?![0-9-])`
rm_zip(text.var)
rm_zip(text.var, extract=TRUE)
> rm_zip(text.var, extract=TRUE)
[[1]]
[1] NA
[[2]]
[1] NA
[[3]]
[1] "12345"
[[4]]
[1] NA
[[5]]
[1] "12345-6789" "12345-6789"
[[6]]
[1] "12345 6789" "12345 6789"
[[7]]
[1] NA