【问题标题】:Data Extraction using Regex使用正则表达式提取数据
【发布时间】:2015-06-10 20:41:42
【问题描述】:

我在文本文件“file.txt”中有数据

食谱和菜单
专家建议
成分
假期和活动
社区
视频
夏季烹饪
扁豆糙米汤
美食 1991 年 1 月
3.5/4
评论 (83)
90%
再来一次
有些汤确实会激发一种类似于爱的奉献精神,这就是其中之一。在寒冷的冬天,当美食编辑思考什么汤的问题
厨师
评论 (83)
产量:制作约 14 杯,供应 6 至 8 杯
成分
5杯鸡汤
1 1/2 杯扁豆,捡起来冲洗
1杯糙米
一个 32 到 35 盎司的西红柿罐头,沥干,保留果汁,切碎
3 根胡萝卜,纵向减半并横向切成 1/4 英寸的小块
1 个洋葱,切碎
1根芹菜,切碎
3瓣大蒜,切碎
1/2 茶匙碎干罗勒
1/2 茶匙碎干牛至
1/4 茶匙碎干百里香
1片月桂叶
1/2 杯切碎的新鲜欧芹叶
2 汤匙苹果醋,或品尝
准备
在一个沉重的水壶中,将肉汤、3 杯水、扁豆、米饭、西红柿和保留的汁液混合,

我想提取IngredientsPreparation之间的数据。
我为此编写了以下正则表达式:-

(?s).*?Ingredients(.*?)Preparation.*

但它是提取
file.txt 和 Preparation 第 3 行的斜体 Ingredients 之间的数据,而不是 Ingredients 和 准备
我应该对我的正则表达式代码进行哪些更改来解决此问题?
提前致谢!

【问题讨论】:

  • 您使用的是什么正则表达式引擎?

标签: regex data-extraction


【解决方案1】:

您可以使用惰性量词 .*? 和第二个 .*

(?s).*\bIngredients\b(.*?)\bPreparation\b

demo

或者你可以使用tempered greedy token然后你不需要第一个.*

(?s)\bIngredients\b(?:(?!\b(?:Ingredients|Preparation)\b).)*\bPreparation\b

demo

【讨论】:

  • 您能告诉我我的回答有什么问题吗?你切换到的那个不检查单词边界,可以匹配Preparations,它可以在Preparation之前,你会得到一个错误的子匹配。
【解决方案2】:

试着让你的第一个 .* 变得贪婪。它会吃掉所有Ingredients,直到Preparation之前的最后一个:

(?s).*Ingredients(.*?)Preparation.*

演示:https://regex101.com/r/mQ5eK5/1

【讨论】:

    【解决方案3】:
    (?s).*?[*]{2}Ingredients[*]{2}(.*?)[*]{2}Preparation[*]{2}.*
    

    [*]{2}告诉正则表达式你想要列表中的一个字符(这里是单个*)两次{2}

    我更喜欢使用字符类而不是转义,我发现它们比这更具可读性:

    (?s).*?\*{2}Ingredients\*{2}(.*?)\*{2}Preparation\*{2}.*
    

    根据您使用的语言,您可能还需要转义反斜杠。

    【讨论】:

      【解决方案4】:

      您可以使用前瞻来检查每一行是否不是Ingredients。通过这种方式,您可以将测试数量限制在行首(而不是测试每个字符):

      (?m)^Ingredients\R((?:(?!Ingredients$).*\R)+?)Preparation$ 
      

      demo

      图案细节:

      (?m)             # switch on the multiline mode (^ and $ match the limit of the line)
      ^Ingredients\R   # "Ingredients" at the start of the line followed by a new line
      (   # capture group 1
          (?:          # open a non-capturing group
              (?!Ingredients$) # negative lookahead to check that the line is not "Ingredients"
              .*\R             # the line
          )+? # repeat until "Preparation"
      )
      Preparation$
      

      注意:由于您没有说明您使用的是什么正则表达式引擎,因此\R 可能不受支持。在这种情况下,请将其替换为 \r?\n

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-04-04
        • 2015-02-24
        • 2017-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-29
        • 2015-05-04
        相关资源
        最近更新 更多