如何用正则或字符串操作拆分含嵌套括号的复杂字符串?
拆分括号外分隔符的成分列表解决方案
问题描述
我有如下成分列表:
Ingredients <- "淀粉(玉米|马铃薯|小麦)|蔬菜(27%)[豌豆(23%)(薄片|颗粒)|胡萝卜颗粒|洋葱粉|菠菜粉] | 油煎面包块(10%)(小麦粉|植物油|盐|酵母)|麦芽糊精|天然风味剂(含牛奶和大豆)|植脂末[含牛奶|矿物质盐(339或340|450或451)] |盐|矿物质盐(氯化钾)|糖|增味剂(621)|植物油|培根粉(0.5%)|欧芹|天然色素(姜黄)|焦糖|食用酸(乳酸)|胡椒提取物"
需要将这些成分拆分后存入dataframe的ingredients列中,但分隔符|在括号()或方括号[]内也有使用,因此只能对**不在括号内的|**进行拆分,最终得到如淀粉(玉米|马铃薯|小麦)、蔬菜(27%)[豌豆(23%)(薄片|颗粒)|胡萝卜颗粒|洋葱粉|菠菜粉]、盐这类完整的成分条目。
解决方案
方法一:使用stringr包实现
library(stringr) # 定义成分字符串 Ingredients <- "淀粉(玉米|马铃薯|小麦)|蔬菜(27%)[豌豆(23%)(薄片|颗粒)|胡萝卜颗粒|洋葱粉|菠菜粉] | 油煎面包块(10%)(小麦粉|植物油|盐|酵母)|麦芽糊精|天然风味剂(含牛奶和大豆)|植脂末[含牛奶|矿物质盐(339或340|450或451)] |盐|矿物质盐(氯化钾)|糖|增味剂(621)|植物油|培根粉(0.5%)|欧芹|天然色素(姜黄)|焦糖|食用酸(乳酸)|胡椒提取物" # 拆分括号外的|并去除条目两端空格 split_ingredients <- str_split(Ingredients, "\\|(?=(?:[^\\[\\]]*\\[[^\\]]*\\])*[^\\[\\]]*$)(?=(?:[^()]*\\([^()]*\\))*[^()]*$)")[[1]] %>% str_trim() # 转换为dataframe ingredients_df <- data.frame(ingredients = split_ingredients, stringsAsFactors = FALSE) # 查看结果 print(ingredients_df)
方法二:使用Base R实现
# 定义成分字符串 Ingredients <- "淀粉(玉米|马铃薯|小麦)|蔬菜(27%)[豌豆(23%)(薄片|颗粒)|胡萝卜颗粒|洋葱粉|菠菜粉] | 油煎面包块(10%)(小麦粉|植物油|盐|酵母)|麦芽糊精|天然风味剂(含牛奶和大豆)|植脂末[含牛奶|矿物质盐(339或340|450或451)] |盐|矿物质盐(氯化钾)|糖|增味剂(621)|植物油|培根粉(0.5%)|欧芹|天然色素(姜黄)|焦糖|食用酸(乳酸)|胡椒提取物" # 拆分并去除空格 split_ingredients <- trimws(strsplit(Ingredients, "\\|(?=(?:[^\\[\\]]*\\[[^\\]]*\\])*[^\\[\\]]*$)(?=(?:[^()]*\\([^()]*\\))*[^()]*$)")[[1]]) # 转为dataframe ingredients_df <- data.frame(ingredients = split_ingredients, stringsAsFactors = FALSE)
正则表达式说明
使用的正则表达式\\|(?=(?:[^\\[\\]]*\\[[^\\]]*\\])*[^\\[\\]]*$)(?=(?:[^()]*\\([^()]*\\))*[^()]*$)作用如下:
- 精准匹配
|符号 - 通过两层正向预查,确保该
|之后的所有方括号[]和圆括号()都是成对闭合的,从而保证拆分只针对不在任何括号内部的|
内容的提问来源于stack exchange,提问作者Jay Bee
相关产品推荐
相关产品推荐

