如何用data.table::tstrsplit按非引号内的句号分割字符串?
解决按未被双引号包裹的句号分割字符串并去除引号的问题
你已经找对了核心的分割逻辑——用正向预查正则确保只拆分不在成对双引号里的句号,现在只需要处理掉结果里多余的双引号就行,给你两种简单的解决方案:
方法一:分割后批量清理引号
先按你原有的正则完成分割,再用gsub去掉每个元素首尾的双引号:
test_string <- c('foo.bar.baz', 'fizz.buzz."ba.zz"') # 第一步:按规则分割字符串 split_result <- strsplit(test_string, '\\.(?=(?:[^\\"]*\\"[^\\"]*\\")*[^\\"]*$)', perl = TRUE) # 第二步:去除每个元素的首尾双引号 clean_result <- lapply(split_result, function(x) gsub('^"|"$', '', x)) # 查看最终结果 clean_result
运行后就能得到你想要的输出:
[[1]] [1] "foo" "bar" "baz" [[2]] [1] "fizz" "buzz" "ba.zz"
方法二:使用data.table::tstrsplit时直接处理
如果你是用data.table的tstrsplit拆分到数据框列中,可以在拆分后直接对列做清理:
library(data.table) dt <- data.table(input_str = test_string) # 拆分字符串到多列 dt[, c("col1", "col2", "col3") := tstrsplit(input_str, '\\.(?=(?:[^\\"]*\\"[^\\"]*\\")*[^\\"]*$)', perl = TRUE)] # 清理每一列的引号 dt[, lapply(.SD, function(x) gsub('^"|"$', '', x)), .SDcols = col1:col3]
补充说明
你原有的正则\\.(?=(?:[^\\"]*\\"[^\\"]*\\")*[^\\"]*$)逻辑完全正确:它匹配句号的同时,通过正向预查确保这个句号后面的引号总数是偶数(意味着不在成对引号内部)。结果保留引号是因为引号属于原字符串的一部分,分割操作不会自动移除它们,所以需要额外的清理步骤。
内容的提问来源于stack exchange,提问作者mlegge
相关产品推荐
相关产品推荐

