正则表达式灾难性回溯;提取单词在特定单词之前以大写字母开头

时间:2018-01-16 15:13:49

标签: python regex backtracking

我对Python世界比较陌生,并且在使用正则表达式方面遇到了麻烦。

我试图在'sale(s)'(或Sale)之前提取公司名称。

我发现我的文本数据中的公司名称都以大写字母开头(其他部分可以是小写或大写或数字或' - '或',例如'Abc Def'或'ABC DEF'或者只是'ABC'或'Abc'),

其中一些表格正在采取('Abc Def'或'Abc & 等表格DEF')。

例如,

来自文字,

  

;;;;;主要客户2005财年,公司派生   其综合收入约为21%(4,782,852美元)   与Kmart Corporation直接交易的持续经营。   电脑产品的销售情况良好。但是,计算机的零件和显示器   分部销售一直在下降。

我只想提取'计算机的零件和显示段'。

所以我试图创建一个正则表达式

((?:(?:[A-Z]+[a-zA-Z\-0-9\']*\.?\s?(?:and |\& )?)+)+?(?:[S|s]ales?\s))

( 1. [A-Z] + [a-zA-Z-0-9 \'] *。?s =>这部分是找到以大写字母开头的单词,其他部分由a-z或A-Z或0-9或 - 或'或'组成。

  1. (?:和| \&)? =>这部分是用和和/或)
  2. 然而,在https://regex101.com/它会发出灾难性的回溯,我读了一些相关的文章,但仍然无法找到解决这个问题的方法。

    你能帮帮我吗?

    谢谢!

1 个答案:

答案 0 :(得分:3)

概述

指出你的模式中的一些事情:

  • [a-zA-Z\-0-9\']您无需在此处转义'。此外,您只需将-放在集合的开头或结尾处,您就不需要将其转义。
  • \&&符号不需要转义。
  • [S|s]表示要匹配S|s,因此您可能会匹配|ales。写这个的正确方法是[Ss]

代码

See regex in use here

(?:(?:[A-Z][\w'-]*|and) +)+(?=[sS]ales?)

结果

输入

  

;;;;;主要客户2005财年,公司从与Kmart Corporation直接交易的持续经营中获得约21%(4,782,852美元)的合并收入。电脑产品的销售情况良好。然而,计算机零件和显示部门的销售一直在下降。

输出

Computer's Parts and Display Segment 

说明

  • (?:(?:[A-Z][\w'-]*|and) +)+匹配一次或多次
    • (?:[A-Z][\w'-]*|and)匹配以下任一项
      • [A-Z][\w'-]*匹配任何大写ASCII字符,后跟任意数量的字符,撇号'或连字符-
      • and按字面意思匹配
    • +匹配一个或多个空格
  • (?=[sS]ales?)确保任何单词saleSalesalesSales跟随
  • 的正向前瞻