在 R 中格式化英国邮政编码

Formatting UK Postcodes in R

我正在尝试格式化作为 R 中不同输入的向量输入的英国邮政编码。

例如,我有以下邮政编码:

postcodes<-c("IV41 8PW","IV408BU","kY11..4hJ","KY1.1UU","KY4    9RW","G32-7EJ")

如何编写通用代码将上述向量的条目转换为:

c("IV41 8PW","IV40 8BU","KY11 4HJ","KY1 1UU","KY4 9RW","G32 7EJ")

即邮政编码的第一部分和第二部分之间相隔一个space并且所有字母都是大写。

编辑:邮政编码的第二部分始终是最后 3 个字符(数字后跟字母的组合)

我想不出一个智能的正则表达式解决方案,所以这里有一个拆分-应用-组合的方法。

sapply(strsplit(sub('^(.*?)(...)$', '\1:\2', postcodes), ':', fixed = TRUE), function(x) {
  paste0(toupper(trimws(x, whitespace = '[.\s-]')), collapse = ' ')
})

#[1] "IV41 8PW" "IV40 8BU" "KY11 4HJ" "KY1 1UU"  "KY4 9RW"  "G32 7EJ" 

这里的逻辑是我们在第1和第2部分之间的字符串中插入一个:(或任何不在数据中的字符)。在 : 上拆分字符串,删除不需要的字符,将其转换为大写并合并为一个字符串。

一种方法:

  1. 转换为大写

  2. 提取字母数字字符

  3. 在最后三个字符

    前粘贴一个space

代码将是:

library(stringr)

postcodes<-c("IV41 8PW","IV408BU","kY11..4hJ","KY1.1UU","KY4    9RW","G32-7EJ")

postcodes <- str_to_upper(postcodes)
sapply(str_extract_all(postcodes, "[:alnum:]"), function(x)paste(paste0(head(x,-3), collapse = ""), paste0(tail(x,3), collapse = "")))
# [1] "IV41 8PW" "IV40 8BU" "KY11 4HJ" "KY1 1UU"  "KY4 9RW"  "G32 7EJ"
# Option 1 using regex: 
res1 <- gsub(
  "(\w+)(\d[[:upper:]]\w+$)", 
  "\1 \2",
  gsub(
    "\W+",
    " ",
    postcodes
  )
)

# Option 2 using substrings:
res2 <- vapply(
  trimws(
    gsub(
      "\W+",
      " ",
      postcodes
    )
  ),
  function(ir){
    paste(
      trimws(
        substr(
          ir, 
          1,
          nchar(ir) -3
        )
      ),
      substr(
        ir, 
        nchar(ir) -2,
        nchar(ir)
      )
    )
  },
  character(1),
  USE.NAMES = FALSE
)

您可以删除所有非单词字符 \W(或 [^[:alnum:]_])的内容,然后在最后 3 个字符前插入 space (.{3})$ \1.

sub("(.{3})$", " \1", toupper(gsub("\W+", "", postcodes)))
#sub("(...)$", " \1", toupper(gsub("\W+", "", postcodes))) #Alternative
#sub("(?=.{3}$)", " ", toupper(gsub("\W+", "", postcodes)), perl=TRUE) #Alternative
#[1] "IV41 8PW" "IV40 8BU" "KY11 4HJ" "KY1 1UU"  "KY4 9RW"  "G32 7EJ"