我有一些文字如下:
foo_text <- c(
"73000 PARIS 74000 LYON",
"75 000 MARSEILLE 68483 LILLE",
"60 MARSEILLE 68483 LILLE"
)
我想在第一个单词后将每个元素一分为二。预期产出:
"73000 PARIS" "74000 LYON" "75000 MARSEILLE" "68483 LILLE" "60 MARSEILLE" "68483 LILLE"
请注意,原文中两个元素之间的空格数不一定相同(例如,巴黎和74000之间的空格数与马赛和68483之间的空格数不同)。此外,有时第一个数字中有空格(例如75000),有时没有空格(例如73000)。
我试图改编这个答案,但没有成功:
(delimitedString = gsub( "^([a-z]+) (.*) ([a-z]+)$", "\\1,\\2", foo_text))
你知道怎么做吗?
我们可以在这里尝试使用strsplit,如下所示:
foo_text <- c(
"73000 PARIS 74000 LYON",
"75 000 MARSEILLE 68483 LILLE",
"60 MARSEILLE 68483 LILLE"
)
output <- unlist(strsplit(foo_text, "(?<=[A-Z])\\s+(?=\\d)", perl=TRUE))
output
[1] "73000 PARIS" "74000 LYON" "75 000 MARSEILLE" "68483 LILLE"
[5] "60 MARSEILLE" "68483 LILLE"
此处使用的正则表达式模式表示在以下情况下拆分:
(?<=[A-Z]) what precedes is an uppercase letter
\\s+ split (and consume) on one or more whitespace characters
(?=\\d) what follows is a digit
另一个可能的解决方案,基于tidyverse
:
library(tidyverse)
foo_text <- c(
"73000 PARIS 74000 LYON",
"75 000 MARSEILLE 68483 LILLE",
"60 MARSEILLE 68483 LILLE"
)
foo_text %>%
str_split("(?<=[:alpha:])\\s+(?=\\d)") %>% flatten %>%
str_remove_all("(?<=\\d)\\s+(?=\\d)")
#> [1] "73000 PARIS" "74000 LYON" "75000 MARSEILLE" "68483 LILLE"
#> [5] "60 MARSEILLE" "68483 LILLE"
您使用的是一种模式^([a-z])(.*)([a-z])$
和gsub
,该模式被锚定并匹配字符串开头和结尾的字符[a-z],该模式不考虑数字,并且由于锚定,无法匹配同一字符串中的多个部分。
对于示例数据,还可以匹配第一部分中包含数字和空格的所有部分,然后是一个或多个没有数字的部分。
library(stringr)
s <- c(
"73000 PARIS 74000 LYON",
"75 000 MARSEILLE 68483 LILLE",
"60 MARSEILLE 68483 LILLE"
)
unlist(str_match_all(s, "\\b\\d[\\d\\s]*(?:\\s+[^\\d\\s]+)+"))
输出
[1] "73000 PARIS" "74000 LYON" "75 000 MARSEILLE" "68483 LILLE"
[5] "60 MARSEILLE" "68483 LILLE"
查看R演示和正则表达式演示。