R语言strsplit与过滤:保留相同值配对中含&的表达式
在R语言中处理配对字符串并保留含
&的匹配项 我来帮你解决这个问题!我们可以分几步实现:先把字符串拆分成单个配对,识别出每组相同元素的配对,最后保留含&的那一个。下面用场景1的例子演示完整代码:
步骤1:拆分字符串,提取所有配对
首先需要把原始字符串里的每个配对提取出来,先去掉外层冗余括号,再按分隔符拆分:
vec1 <- "((PAUL & SAM) | (PAUL | SAM) | (NINA & SAM) | (NINA | SAM) | (NINA & PAUL) | (NINA | PAUL))" # 去掉最外层的两层括号 clean_str <- gsub("^\\(\\(|\\)\\)$", "", vec1) # 按" | "拆分得到每个带括号的配对 pairs_with_paren <- strsplit(clean_str, " \\| ")[[1]] # 去掉每个配对的括号 pairs <- gsub("^\\(|\\)$", "", pairs_with_paren)
运行后pairs会得到:
[1] "PAUL & SAM" "PAUL | SAM" "NINA & SAM" "NINA | SAM" "NINA & PAUL" "NINA | PAUL"
步骤2:为每个配对生成唯一标识(键)
对于每个配对,我们把两个元素拆分后排序,这样不管是A & B还是B | A,都会生成相同的键,方便识别同组配对:
# 定义生成键的函数:拆分元素→排序→用逗号连接 get_pair_key <- function(pair_str) { elements <- strsplit(pair_str, " & | \\| ")[[1]] paste(sort(elements), collapse = ",") } # 为每个配对生成键 pair_keys <- sapply(pairs, get_pair_key) # 组合成数据框方便后续处理 pair_df <- data.frame(pair = pairs, key = pair_keys, stringsAsFactors = FALSE)
此时pair_df的内容是:
pair key 1 PAUL & SAM PAUL,SAM 2 PAUL | SAM PAUL,SAM 3 NINA & SAM NINA,SAM 4 NINA | SAM NINA,SAM 5 NINA & PAUL NINA,PAUL 6 NINA | PAUL NINA,PAUL
步骤3:过滤保留含&的配对
我们可以按键分组,每组只保留包含&的配对,这里提供两种实现方式:
方式1:用dplyr分组过滤
library(dplyr) filtered_pairs <- pair_df %>% group_by(key) %>% filter(grepl("&", pair)) %>% ungroup() %>% pull(pair)
方式2:用Base R实现(无需额外包)
# 按键分组,取每组中含&的元素 filtered_pairs <- sapply(split(pair_df, pair_df$key), function(group) { group$pair[grepl("&", group$pair)] }) # 转换为无命名向量 filtered_pairs <- unname(filtered_pairs)
最终得到的filtered_pairs就是目标结果:
[1] "PAUL & SAM" "NINA & SAM" "NINA & PAUL"
处理不同长度的vec1/vec2
如果vec1和vec2是长度大于1的向量,我们可以把上述逻辑封装成函数批量处理:
filter_keep_and_pairs <- function(vec) { lapply(vec, function(x) { # 重复字符串清理与拆分步骤 clean_str <- gsub("^\\(\\(|\\)\\)$", "", x) pairs_with_paren <- strsplit(clean_str, " \\| ")[[1]] pairs <- gsub("^\\(|\\)$", "", pairs_with_paren) # 生成配对键 get_pair_key <- function(pair_str) { elements <- strsplit(pair_str, " & | \\| ")[[1]] paste(sort(elements), collapse = ",") } pair_keys <- sapply(pairs, get_pair_key) pair_df <- data.frame(pair = pairs, key = pair_keys, stringsAsFactors = FALSE) # Base R过滤 filtered <- sapply(split(pair_df, pair_df$key), function(group) { group$pair[grepl("&", group$pair)] }) unname(filtered) }) } # 测试批量处理 vec1 <- c("((PAUL & SAM) | (PAUL | SAM))", "((NINA & PAUL) | (NINA | PAUL))") result <- filter_keep_and_pairs(vec1)
运行后result是一个列表,每个元素对应原向量中元素的过滤结果:
[[1]] [1] "PAUL & SAM" [[2]] [1] "NINA & PAUL"
内容的提问来源于stack exchange,提问作者Newbie
相关产品推荐
相关产品推荐

