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

regex catastrophic backtracking ; extracting words starts with capital before the specific word

我是 Python 世界的新手,在使用正则表达式时遇到问题。

我正在尝试提取单词 'sale(s)'(或销售)之前的公司名称。

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

其中一些采取类似 ('Abc and Def' 或 'Abc & Def') 的形式。

例如,

从文中,

;;;;;PRINCIPAL CUSTOMERS In fiscal 2005, the Company derived approximately 21% (,782,852) of its consolidated revenues from continuing operations from direct transactions with Kmart Corporation. Sales of Computer products was good. However, Computer's Parts and Display Segment sale has been decreasing.

我只想提取'Computer's Parts and Display Segment'

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

((?:(?:[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. (?:和|\&)? => 这部分是用 and 或 & )
  2. 来匹配单词

然而,在https://regex101.com/时,它调用了灾难性的回溯,我阅读了一些相关文章,但仍然没有找到解决这个问题的方法。

你能帮帮我吗?

谢谢!

概览

指出您的模式中的一些内容:

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

代码

See regex in use here

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

结果

输入

;;;;;PRINCIPAL CUSTOMERS In fiscal 2005, the Company derived approximately 21% (,782,852) of its consolidated revenues from continuing operations from direct transactions with Kmart Corporation. Sales of Computer products was good. However, Computer's Parts and Display Segment sale has been decreasing.

输出

Computer's Parts and Display Segment 

说明

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