在R中如何将字符串在第一个整数处分割?

5

注意:我已经阅读了在字符串中第一次出现整数时分割字符串,但我的要求不同,因为我想使用R。

假设我有以下示例数据框:

> df = data.frame(name_and_address =
      c("Mr. Smith12 Some street",
        "Mr. Jones345 Another street",
        "Mr. Anderson6 A different street"))
> df
                  name_and_address
1          Mr. Smith12 Some street
2      Mr. Jones345 Another street
3 Mr. Anderson6 A different street

我想在遇到第一个整数时将字符串拆分开。请注意,这些整数的长度可能不同。

期望的输出可以如下所示:

[[1]]
[1] "Mr. Smith"
[2] "12 Some street",

[[2]]
[1] "Mr. Jones"
[2] "345 Another street",

[[3]]
[1] "Mr. Anderson"
[2] "6 A different street"

我已经尝试过以下方法,但我无法正确地得到正则表达式:
# Attempt 1 (Does not work)
library(data.table)
tstrsplit(df,'(?=\\d+)', perl=TRUE, type.convert=TRUE)

# Attempt 2 (Does not work)
library(stringr)
str_split(df, "\\d+")

我猜你想说的是“第一个数字”,对吗? - Wiktor Stribiżew
@WiktorStribiżew,是的,我希望在长度不同的整数的第一个数字上进行拆分。 - NM_
你可以尝试在每行上使用(?<!\\\d)(?=\\d+)的零宽匹配进行拆分。正向回顾(?<!\\d)断言当前字符串位置(将其视为连续字符之间的位置)不是数字前缀。正向预查(?=\\d+)断言当前字符串位置后跟一个或多个数字。演示 - Cary Swoveland
2个回答

4
我会在这里使用sub
df$name <- sub("(\\D+).*", "\\1", df$name_and_address)
df$address <- sub(".*?(\\d+.*)", "\\1", df$name_and_address)

3
您可以使用tidyr::extract
library(tidyr)
df <- df %>% 
    extract("name_and_address", c("name", "address"), "(\\D*)(\\d.*)")
## => df
##           name              address
## 1    Mr. Smith       12 Some street
## 2    Mr. Jones   345 Another street
## 3 Mr. Anderson 6 A different street

(\D*)(\d.*) 正则表达式匹配以下内容:

  • (\D*) - 第一组:零个或多个非数字字符。
  • (\d.*) - 第二组:一个数字,后面跟任意数量的尽可能多的字符。

另一种使用 stringr::str_split 的解决方案也是可行的:

str_split(df$name_and_address, "(?=\\d)", n=2)
## => [[1]]
## [1] "Mr. Smith"      "12 Some street"

## [[2]]
## [1] "Mr. Jones"          "345 Another street"

## [[3]]
## [1] "Mr. Anderson"         "6 A different street"
(?=\d)正向预查在数字之前找到一个位置,n=2告诉stringr::str_split最多只分割成两个块。
如果字符串中没有数字,则基于R的方法不返回任何内容。
df = data.frame(name_and_address = c("Mr. Smith12 Some street", "Mr. Jones345 Another street", "Mr. Anderson6 A different street", "1 digit is at the start", "No digits, sorry."))

df$name <- sub("^(?:(\\D*)\\d.*|.+)", "\\1", df$name_and_address)
df$address <- sub("^\\D*(\\d.*)?", "\\1", df$name_and_address)
df$name
# => [1] "Mr. Smith"    "Mr. Jones"    "Mr. Anderson" ""             ""
df$address
# => [1] "12 Some street"          "345 Another street"     
#    [3] "6 A different street"    "1 digit is at the start"         ""                       

查看在线 R 演示。它还支持第一个数字是字符串中的第一个字符的情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接