这里我有一个简单的字符串;
input_string <- "P24928 [1909-1922]; [1923-1936]; P08775 [1909-1922]; [1923-1936]"
字符串我希望它将第一部分,即P#####,粘贴在第二组括号之前,这样字符串将是:
P#####
"P24928 [1909-1922]; P24928 [1922-1923]; P08775 [1909-1922]; P08775 [1922-1923]"
型
u91tlkcl1#
我们可以使用gregexpr来找到P*\s-regmatches。我们希望它们作为一个空格和一个空格之间的空值的替代品。我们可以使用``regmatches<-()函数有效地做到这一点(也可以用学分来淋浴 @thelatemail!)。
gregexpr
P*\s
regmatches
()
> f <- \(x) { + sbs <- regmatches(x, gregexpr(r"{P\d+\s(?=\[)}", x, perl=TRUE)) + mtc <- gregexpr(r"{(?<=;\s)(?=\[)}", x, perl=TRUE) + regmatches(x, mtc) <- sbs + x + } > f(x) [1] "P24928 [1909-1922]; P24928 [1923-1936]; P08775 [1909-1922]; P08775 [1923-1936]"
字符串请注意,这已经是矢量化,即您可以执行以下操作,
> f(c(x, x, x)) [1] "P24928 [1909-1922]; P24928 [1923-1936]; P08775 [1909-1922]; P08775 [1923-1936]" [2] "P24928 [1909-1922]; P24928 [1923-1936]; P08775 [1909-1922]; P08775 [1923-1936]" [3] "P24928 [1909-1922]; P24928 [1923-1936]; P08775 [1909-1922]; P08775 [1923-1936]"
型顺便说一句,在R之外处理这样的任务可能更有效。如果我们使用awk,并且假设我们有一个文本文件 foo.txt,其行格式为x,我们可以这样处理它:
x
$ awk -v OFS=' ' '{print $1, $2, $1 FS $3, $4, $5, $4 FS $6}' foo.txt P24928 [1909-1922]; P24928 [1923-1936]; P08775 [1909-1922]; P08775 [1923-1936] P24928 [1909-1922]; P24928 [1923-1936]; P08775 [1909-1922]; P08775 [1923-1936] P24928 [1909-1922]; P24928 [1923-1936]; P08775 [1909-1922]; P08775 [1923-1936]
x <- "P24928 [1909-1922]; [1923-1936]; P08775 [1909-1922]; [1923-1936]"
iqxoj9l92#
library(tidyverse) input_string <- "P24928 [1909-1922]; [1923-1936]; P08775 [1909-1922]; [1923-1936]" parts <- input_string |> str_split_1("\\s") |> str_remove(";$") parts |> matrix(ncol = 3, byrow = TRUE) |> as.data.frame() |> mutate(str_c(V1, " ", V2, "; ", V1, " ", V3, "; ")) |> pull(last_col()) |> str_flatten() |> str_remove(";\\s+$") #> [1] "P24928 [1909-1922]; P24928 [1923-1936]; P08775 [1909-1922]; P08775 [1923-1936]"
字符串创建于2023-12-10使用reprex v2.0.2
olmpazwi3#
这里还有一个:
library(tidyverse) input_string %>% as_tibble() %>% separate_rows(value, sep = " ") %>% group_by(group =as.integer(gl(n(),3,n()))) %>% mutate(x = paste(first(value), value)) %>% filter(grepl("\\[", x)) %>% pull() %>% paste(., collapse = " ")
个字符
v440hwme4#
下面是一个使用正则表达式的更简洁的解决方案:
library(tidyverse) as.data.frame(input_string) %>% separate_rows(input_string, sep = "(?<=;)\\s(?=[A-Z])") %>% mutate(input_string = str_replace_all(input_string, "(\\w+)(.*?;)(.*$)", "\\1\\2 \\1\\3")) %>% summarise(input_string = str_c(input_string, collapse = " ")) # A tibble: 1 × 1 input_string <chr> 1 P24928 [1909-1922]; P24928 [1923-1936]; P08775 [1909-1922]; P08775 [1923-1936]
字符串我们首先使用正向后看将字符串分成组((?<=;))和前瞻项((?=[A-Z])),它们实现了一条指令,在左边有一个空格,右边有一个大写字母的空白处进行分隔。然后我们将得到的字符串定义为三个捕获组,我们使用反向引用\\1,\\2,和\\3将第一个子字符串粘贴到第二个子字符串之后。最后,我们将分离的部分折叠回单个字符串。
(?<=;)
(?=[A-Z])
\\1
\\2
\\3
编辑:
如果你的字符串总是有六个子字符串和两个“组”,就像例子中那样,那么一个简单的一行代码就足够了:
str_replace_all(input_string, "(\\w+)(.*?;)(.*?;) (\\w+)(.*?;)(.*?$)", "\\1\\2 \\1\\3 \\4\\5 \\4\\6") [1] "P24928 [1909-1922]; P24928 [1923-1936]; P08775 [1909-1922]; P08775 [1923-1936]"
型当然,这种解决方案可以适用于每组更多的元素和更多的组。
4条答案
按热度按时间u91tlkcl1#
我们可以使用
gregexpr
来找到P*\s
-regmatches
。我们希望它们作为一个空格和一个空格之间的空值的替代品。我们可以使用``regmatches<-()
函数有效地做到这一点(也可以用学分来淋浴 @thelatemail!)。字符串
请注意,这已经是矢量化,即您可以执行以下操作,
型
顺便说一句,在R之外处理这样的任务可能更有效。如果我们使用awk,并且假设我们有一个文本文件 foo.txt,其行格式为
x
,我们可以这样处理它:型
型
iqxoj9l92#
字符串
创建于2023-12-10使用reprex v2.0.2
olmpazwi3#
这里还有一个:
个字符
v440hwme4#
下面是一个使用正则表达式的更简洁的解决方案:
字符串
我们首先使用正向后看将字符串分成组(
(?<=;)
)和前瞻项((?=[A-Z])
),它们实现了一条指令,在左边有一个空格,右边有一个大写字母的空白处进行分隔。然后我们将得到的字符串定义为三个捕获组,我们使用反向引用\\1
,\\2
,和\\3
将第一个子字符串粘贴到第二个子字符串之后。最后,我们将分离的部分折叠回单个字符串。编辑:
如果你的字符串总是有六个子字符串和两个“组”,就像例子中那样,那么一个简单的一行代码就足够了:
型
当然,这种解决方案可以适用于每组更多的元素和更多的组。