从字符串中提取州名缩写和邮政编码

时间:2017-05-04 17:28:58

标签: r regex text-extraction zipcode

我想从以下字符串中提取州名缩写(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:包含电话号码

3 个答案:

答案 0 :(得分:6)

提取邮政编码的代码:

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实际应为{{1} }}。如果您无法控制数据源,但确定它们是美国代码,则可以根据需要在左侧填充0。但是,由于您正在寻找4或5个字符的解决方案,因此可以使用:

提取邮政编码的代码(查找前面的空格和后面的换行符,以便不选择部分电话号码或地址)

04330

提取州代码的代码:

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

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

答案 1 :(得分:3)

我使用地址作为输入而不是文字,看看它是否适合你的情况。

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

<强>输入

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

答案 2 :(得分:2)

  

谢谢@Rahul。两者都很棒。至少你能告诉我如何使用Notepad ++吗?

     

使用Notepad ++提取

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

  2. Ctrl + F 转到Find。这将打开搜索对话框。选择带有正则表达式Replace的{​​{1}}标签搜索,然后替换为([A-Z]{2}\s*\d{4,5})$。这将搜索州名缩写和邮政编码,并将它们放在换行符中,\n-\1-\n作为前缀和后缀。

  3. enter image description here

    1. 现在转到-标签。选中Mark复选框,然后使用Bookmark Line进行搜索,然后按-(.*?)-。这将标记状态abb和ZIP,它们位于换行符Mark All
    2. enter image description here

      1. 现在转到搜索-书签-->删除未标记的行
      2. Result

        1. 最后使用-->搜索并替换为空字符串。
        2. enter image description here

          <强>更新

          那么现在还会有电话号码吗?在这种情况下,您只需要在步骤2中从正则表达式中删除$。要使用的正则表达式为^-|-$。休息所有步骤都是一样的。