【问题标题】:Extract state abbreviation and zip code from strings从字符串中提取州缩写和邮政编码
【发布时间】:2017-05-04 17:28:57
【问题描述】:

我想从以下字符串中提取州缩写(2 个字母)和邮政编码(4 个或 5 个数字)

    address <- "19800 Eagle River Road, Eagle River AK 99577
              907-481-1670
              230 Colonial Promenade Pkwy, Alabaster AL 35007
              205-620-0360
              360 Connecticut Avenue, Norwalk CT 06854
              860-409-0404
              2080 S Lincoln, Jerome ID 83338
              208-324-4333
              20175 Civic Center Dr, Augusta ME 4330
              207-623-8223
              830 Harvest Ln, Williston VT 5495
              802-878-5233
              "

对于邮政编码,我尝试了一些我在这里找到的方法,但主要是因为 5 个数字街道地址或只有 4 个数字的邮政编码没有奏效

    text <- readLines(textConnection(address))

    library(stringi)
    zip <- stri_extract_last_regex(text, "\\d{5}")
    zip

    library(qdapRegex)
    rm_zip3 <- rm_(pattern="(?<!\\d)\\d{5}(?!\\d)", extract = TRUE)
    zip <- rm_zip3(text)
    zip

    [1] "99577" "1670"  "35007" "0360"  "06854" "0404"  "83338" "4333"  "4330"  "8223"  "5495"  "5233"  NA 

对于州缩写,我不知道如何提取

任何帮助表示赞赏!提前致谢!

修改 1:包括电话号码

【问题讨论】:

  • 您想以编程方式或仅使用正则表达式来完成它?我的意思是它也可以通过记事本++来完成
  • states &lt;- str_extract(text, "\\b[A-Z]+(?=\\s+\\d{5}$)")
  • 谢谢@Rahul。两者都会很棒。至少你能告诉我如何用 Notepad++ 做到这一点吗?
  • @WiktorStribiżew:谢谢!最后两行我仍然有错误"AK" "AL" "CT" "ID" NA NA
  • @IloveCatandPython 将{5} 修改为{4,5},如下所示:states &lt;- str_extract(text, "\\b[A-Z]+(?=\\s+\\d{5}$)")

标签: r regex text-extraction zipcode


【解决方案1】:

提取邮政编码的代码:

zip <- str_extract(text, "\\d{5}")

提取状态码的代码:

states <- str_extract(text, "\\b[A-Z]{2}(?=\\s+\\d{5}$)")

提取电话号码的代码:

phone <- str_extract(text, "\\b\\d{3}-\\d{3}-\\d{4}\\b")

注意:您的数据似乎有问题,因为最后 2 个邮政编码应该是 5 个字符而不是 4 个字符。4330 实际上应该是 04330。如果您无法控制数据源,但确定它们是美国代码,您可以根据需要在左侧填充 0。但是,由于您正在寻找 4 或 5 个字符的解决方案,您可以使用:

提取邮政编码的代码(寻找前面的空格和后面的换行符,这样电话号码或地址的一部分就不会被选中)

zip <- str_extract(text, "(?<= )\\d{4,5}(?=\\n|$)")

提取状态码的代码:

states <- str_extract(text, "\\b[A-Z]{2}(?=\\s+\\d{4,5}$)")

演示:https://regex101.com/r/7Im0Mu/2

【讨论】:

  • 谢谢!我更新了地址以包括电话号码。你可以相应地修改你的代码吗?此外,看起来state 没有按预期工作[1] "AK" NA "AL" NA "CT" NA "ID" NA "ME" NA "VT" NA NA
  • 添加了电话号码的代码。我认为您会在每条备用线路上获得额外的NA,因为现在您的电话号码在另一条线路上,str_extract 尝试提取每条线路的邮政编码,但无法在第二行找到包含电话号码的任何邮政编码
  • 抱歉不清楚!添加电话号码后,其中的最后4位数字也会在提取后显示[1] "99577" "1670" "35007" "0360" "06854" "0404" "83338" "4333" "4330" "8223" "5495" "5233" NA
  • 抱歉,我以为我已经解决了。我现在更新了代码和演示链接,看看。您也会在这里遇到同样的问题,例如 state 代码,但由于文本中的行数,每个备用代码都是 NA
【解决方案2】:

我使用 address 作为输入而不是文本,看看它是否适合您的情况。

关于正则表达式的假设: 两个大写字母后跟 4 或 5 个数字字母表示州和邮编,电话号码总是在下一行。

输入

address <- "19800 Eagle River Road, Eagle River AK 99577
907-481-1670
230 Colonial Promenade Pkwy, Alabaster AL 35007
205-620-0360
360 Connecticut Avenue, Norwalk CT 06854
860-409-0404
2080 S Lincoln, Jerome ID 83338
208-324-4333
20175 Civic Center Dr, Augusta ME 4330
207-623-8223
830 Harvest Ln, Williston VT 5495
802-878-5233
"

我使用的是stringr库,你可以选择任何其他的来提取你想要的信息。

library(stringr)
df <- data.frame(do.call("rbind",strsplit(str_extract_all(address,"[A-Z][A-Z]\\s\\d{4,5}\\s\\d{3}-\\d{3}-\\d{4}")[[1]],split="\\s|\\n")))
names(df) <- c("state","Zip","Phone")

编辑

如果有人想使用文本作为输入,

text <- readLines(textConnection(address))
text <- data.frame(text)
st_zip <- setNames(data.frame(str_extract_all(text$text,"[A-Z][A-Z]\\s\\d{4,5}",simplify = T)),"St_zip")
pin <- setNames(data.frame(str_extract_all(text$text,"\\d{3}-\\d{3}-\\d{4}",simplify = T)),"pin")
st_zip <- st_zip[st_zip$St_zip != "",]
df1 <- setNames(data.frame(do.call("rbind",strsplit(st_zip,split=' '))),c("State","Zip"))
pin <- pin[pin$pin != "",]
df2 <- data.frame(cbind(df1,pin))

输出

    State   Zip    pin
1    AK 99577 907-481-1670
2    AL 35007 205-620-0360
3    CT 06854 860-409-0404
4    ID 83338 208-324-4333
5    ME  4330 207-623-8223
6    VT  5495 802-878-5233

【讨论】:

  • 谢谢!现在可以了。是否可以修改您的代码以使用从文件中读取文本或至少使用text 而不是address
  • @IloveCatandPython 查看编辑,希望对您有所帮助
  • 感谢@K..pradeeep!非常感激!要是我能选择多个答案就好了。
【解决方案3】:

谢谢@Rahul。两者都会很棒。至少你能告诉我如何用 Notepad++ 做到这一点吗?


使用记事本++提取

  1. 首先将整个数据复制到一个文件中。

  2. 通过按 Ctrl + F 转到 Find。这将打开搜索对话框。使用正则表达式([A-Z]{2}\s*\d{4,5})$ 选择Replace 选项卡搜索并替换为\n-\1-\n。这将搜索州缩写和邮政编码并将它们放在新行中,并以- 作为前缀和后缀。

  1. 现在转到Mark 选项卡。选中 Bookmark Line 复选框,然后使用 -(.*?)- 搜索并按 Mark All。这将用 - 标记换行符中的状态 abb 和 ZIP。

  1. 现在转到搜索--&gt;书签--&gt;删除未标记的行

  1. 最后用^-|-$搜索并替换为空字符串。


更新

所以现在也会有电话号码?在这种情况下,您只需在步骤 2 中从正则表达式中删除 $。要使用的正则表达式将是 ([A-Z]{2}\s*\d{4,5})。其余所有步骤将相同。

【讨论】:

  • 谢谢@Rahul!它对我不起作用link(请注意,我更新了地址以包含电话号码)
  • @IloveCatandPython:那么现在也有电话号码了?在这种情况下,您只需在步骤 2 中从正则表达式中删除 $。要使用的正则表达式将是 ([A-Z]{2}\s*\d{4,5})。其余所有步骤都将相同。
  • Notepad++ 一直告诉我Find: Can't find the text "([A-Z]{2}\s*\d{4,5})"。我需要为它安装任何插件吗? TY
  • 您必须在Replace 选项卡中搜索并相应地进行替换。请阅读步骤。
  • 谢谢!我没有意识到你必须在Search Mode中选择Regular expression
猜你喜欢
  • 2015-05-07
  • 2014-01-31
  • 2015-09-25
  • 2021-12-16
  • 2013-04-05
  • 2023-02-21
  • 1970-01-01
  • 2018-10-28
  • 1970-01-01
相关资源
最近更新 更多