如何修改正则以捕获标签间多词内容并转换为指定字典结构
问题与解决方案
问题描述
现有如下格式的字符串:
test = "<bos> <start> some fruits: <mid> apple, oranges <mid> also pineapple <start> some animals: <mid> dogs, cats <eos>"
需要将其转换为{字符串: [字符串列表]}格式的字典:
{"some fruits:" : ["apple, oranges", "also pineapple"], "some animals:" : ["dogs, cats"]}
转换规则:
- 两个
<mid>标签之间的内容作为单个字符串; - 当遇到
<start>标签时,代表新的字典条目开始。
原使用的正则表达式仅能匹配字母数字下划线组成的单词语法内容,无法捕获包含空格、逗号等特殊字符的多词内容,原代码如下:
import re test = "<bos> <start> some fruits: <mid> apple, oranges <mid> also pineapple <start> some animals: <mid> dogs, cats <eos>" test_dict = {} res = re.finditer(r'<start>\s(\w+)\s<mid>\s(\w+(?:\s<mid>\s\w+)*)', test) for match in res: test_dict[match.group(1)] = match.group(2).split(' <mid> ')
解决方案
核心是修改正则中的匹配规则,将仅匹配字母数字下划线的\w+替换为能匹配任意非标签内容的模式,确保捕获包含空格、逗号的完整内容。
调整后的正则表达式
推荐使用以下正则,通过非贪婪匹配和正向预查精准定位标签间的内容:
res = re.finditer(r'<start>\s([^<]+?)\s<mid>\s(.+?)(?=\s(?:<start>|<eos>))', test)
各部分说明:
[^<]+?:非贪婪匹配所有不是<的字符,直到遇到下一个标签的起始符号<,确保捕获<start>后的完整标题内容;(.+?)(?=\s(?:<start>|<eos>)):非贪婪匹配所有内容,直到遇到<start>(新条目开始)或<eos>(字符串结束),确保捕获当前条目下的所有<mid>内容。
完整代码示例
import re test = "<bos> <start> some fruits: <mid> apple, oranges <mid> also pineapple <start> some animals: <mid> dogs, cats <eos>" test_dict = {} # 匹配符合要求的条目 res = re.finditer(r'<start>\s([^<]+?)\s<mid>\s(.+?)(?=\s(?:<start>|<eos>))', test) for match in res: # 获取键并去除可能的前后空格 key = match.group(1).strip() # 将捕获的内容按<mid>拆分,并去除每个元素的前后空格 values = [item.strip() for item in match.group(2).split(' <mid> ')] test_dict[key] = values print(test_dict)
运行结果
{'some fruits:': ['apple, oranges', 'also pineapple'], 'some animals:': ['dogs, cats']}
内容的提问来源于stack exchange,提问作者Rahul Dev
相关产品推荐
相关产品推荐

