【问题标题】:REGEX: extract different types of house numbers from string (address) using stringr正则表达式:使用 stringr 从字符串(地址)中提取不同类型的门牌号
【发布时间】:2020-04-11 04:54:47
【问题描述】:

这是一个包含各种街道条目的数据集(一列),其中门牌号可以出现在不同的位置、组合和长度。我的目标是将街道名称和门牌号码分开,并且使用正则表达式已经走到了这一步:

regex <- "[[:digit:]]{1,}[[:punct:]]?\\s?[-0-9]{0,}[A-z]{0,2}\\b"
streets <- data.frame(STR_orig = c("StreetA 11-13", 
                           "StreetB 100", 
                           "StreetC 25a",
                           "12 StreetD",
                           "13 StreetE WE",
                           "StreetF 81A+B",
                           "StreetG 1,2,3",
                           "StreetH 1, 2, 3",
                           "StreetI 8/9",
                           "StreetJ 11 - 13"))
streets <- streets %>%
    mutate(STR = gsub(regex, "\\1", STR_orig), 
    NR = stri_extract_all(STR_orig, regex=regex))

> streets
          STR_orig         STR      NR
1    StreetA 11-13    StreetA    11-13
2      StreetB 100    StreetB      100
3      StreetC 25a    StreetC      25a
4       12 StreetD     StreetD     12 
5    13 StreetE WE  StreetE WE     13 
6    StreetE 13 WE    StreetE    13 WE
7    StreetF 81A+B  StreetF +B     81A
8    StreetG 1,2,3   StreetG ,  1,2, 3
9  StreetH 1, 2, 3  StreetH ,  1, 2, 3
10     StreetI 8/9    StreetI      8/9
11 StreetJ 11 - 13 StreetJ  -   11, 13

我仍然没有捕捉到 81A+B 中的 +,StreetJ 之后的 - 没有被删除,并且空间有时仍然存在。也可能会出现 WE、N 等点。

我必须在我的正则表达式中进行哪些更改才能正确解决这个问题?我已经尝试了很多...感谢您的任何建议!

PS:目前输出是一个列表,当元素分离时我不太清楚,请参见案例 8 和 9。此外,我也有兴趣将列表元素合并到一个 chr 条目(unlist 不工作?)。

已编辑:

期望的输出可以是

          STR_orig         STR      NR
1    StreetA 11-13     StreetA   11-13 ## w/o space chr
2      StreetB 100     StreetB     100 
3      StreetC 25a     StreetC     25a 
4       12 StreetD     StreetD      12
5    13 StreetE WE     StreetE   13 WE
6    StreetE 13 WE     StreetE   13 WE
7    StreetF 81A+B     StreetF   81A+B
8    StreetG 1,2,3     StreetG   1,2,3
9  StreetH 1, 2, 3     StreetH 1, 2, 3
10     StreetI 8/9     StreetI     8/9
11 StreetJ 11 - 13     StreetJ 11 - 13

【问题讨论】:

  • 我作为人类可能无法完成您要求的任务。 StreetG 1,2,3 怎么是门牌号?除非您对确切的街道号码有明确的定义,否则很难编写正则表达式来为您完成。想要的结果到底是什么?
  • 我理解这个问题。有些条目将“1 - 7”指定为门牌号,而其他条目则写为“STR. 85, 87, 89”(因为只有奇数位于街道的这一侧)。甚至还有一个条目显示为“10,12,13 AND 14”。我的想法是条目应该以数字开头,随后的所有内容(带标点符号 + - /、最多 2 个字母等的字符组合)都应提取为门牌号。

标签: r regex stringr


【解决方案1】:

您可以查找所有没有编号的名称,而不是取最长的名称,假设这是街道名称,并将其写在STR 列中。然后subSTRSTR_orig得到NR

streets$STR <- lapply(
 regmatches(streets$STR_orig,  gregexpr("[[:alpha:]]+", streets$STR_orig))
 , function(x)  x[which.max(lapply(x, nchar))])
streets$NR <- apply(streets, 1, function(x) trimws(sub(x[2], "", x[1])))
streets
#          STR_orig     STR      NR
#1    StreetA 11-13 StreetA   11-13
#2      StreetB 100 StreetB     100
#3      StreetC 25a StreetC     25a
#4       12 StreetD StreetD      12
#5    13 StreetE WE StreetE  13  WE
#6    StreetF 81A+B StreetF   81A+B
#7    StreetG 1,2,3 StreetG   1,2,3
#8  StreetH 1, 2, 3 StreetH 1, 2, 3
#9      StreetI 8/9 StreetI     8/9
#10 StreetJ 11 - 13 StreetJ 11 - 13

【讨论】:

    【解决方案2】:

    这是一个带有base R 的解决方案,其中使用了gsub()。也许您可以使用下面的代码来获得所需的输出:

    streets$STR <- gsub(".*?(Street\\w).*","\\1",streets$STR_orig)
    streets$NR <- gsub("(.*?)Street\\w\\s(.*)","\\1\\2",streets$STR_orig)
    

    这样

    > streets
              STR_orig     STR         NR
    1    StreetA 11-13 StreetA      11-13
    2      StreetB 100 StreetB        100
    3      StreetC 25a StreetC        25a
    4       12 StreetD StreetD 12 StreetD
    5    13 StreetE WE StreetE      13 WE
    6    StreetF 81A+B StreetF      81A+B
    7    StreetG 1,2,3 StreetG      1,2,3
    8  StreetH 1, 2, 3 StreetH    1, 2, 3
    9      StreetI 8/9 StreetI        8/9
    10 StreetJ 11 - 13 StreetJ    11 - 13
    

    【讨论】:

      猜你喜欢
      • 2018-12-03
      • 1970-01-01
      • 2022-01-18
      • 2015-12-17
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多