Python2.X:Regex查找所有以“quot;结尾的公司名称;。股份有限公司;

Python2.X:Regex查找所有以“quot;结尾的公司名称;。股份有限公司;,python,regex,Python,Regex,我正试图从新闻稿中提取公司名称。例如,下面是一份新闻稿的片段(法语),其中包含以.inc结尾的七家公司的名单 有效地,魁北克省可利用浮雕制造业的起源,不沥青Vrac运输公司,9163-6704魁北克公司,企业德尼·杜普雷公司,杰恩·马查多公司,Impact Technologie Environmentale inc.,Les Enterprises Luc Clément inc.et运输Vrac Global International inc. 我正在尝试使用以下代码提取所有名称: aa

我正试图从新闻稿中提取公司名称。例如,下面是一份新闻稿的片段(法语),其中包含以
.inc
结尾的七家公司的名单

有效地,魁北克省可利用浮雕制造业的起源,不沥青Vrac运输公司9163-6704魁北克公司企业德尼·杜普雷公司杰恩·马查多公司Impact Technologie Environmentale inc.Les Enterprises Luc Clément inc.et运输Vrac Global International inc.

我正在尝试使用以下代码提取所有名称:

aa = re.findall('inc\.,? (.*?inc\.)', text)
我确实捕获了不少,但由于某些原因,我无法计算,无法将它们全部提取出来。这看起来很琐碎,但却让我受了几个小时的折磨


感谢您的帮助

在这种情况下,您可以避免使用
regex
,而是尝试:

text.split(“,”)

然后遍历创建的
列表,查找
“.inc”
在这种情况下,您可以避免使用
regex
,而是尝试:

text.split(“,”)
然后遍历创建的
列表
,查找
“.inc”

摘要 使用模块(而不是
re
)可以使用此解决方案


密码 选择1 这是原始正则表达式,仅与
inc.
匹配。这也不允许公司名称包含
et
。有关更全面的正则表达式,请参见选项2

选择2 对于还检查其他公司实体(如
ltd.
sons
)的更全面的正则表达式,可以使用以下正则表达式

注意:在某些风格的正则表达式中,您可以使用
\K
标记。此标记重置报告匹配的起点(以前使用的任何字符不再包括在最终匹配中)。如果您的正则表达式引擎支持
\K
标记(并且没有将其转换为文本
K
),则可以使用以下方法(有效地消除了捕获组的需要)


后果 输入 有效的,魁北克省可利用克罗地亚的存在主题 ces企业可用的浮雕制作产地 Plusiers sociétés,不沥青Vrac运输公司,9163-6704 魁北克公司、Denis Dupréinc.企业、Gestion Jean M.Machado Impact Technologie Environmentale inc.,Les Enterprises Luc 克莱门特运输公司Vrac环球国际公司

输出
解释 选择1
  • [\p{Lu}\p{N}]
    匹配集合中的任何内容(在本例中为
    \p{Lu}
    -任何语言中的任何大写字符(包括用于大写法语字符的Unicode和用于数字公司的数字)
  • (?:(?!et)[^,]*)*
    匹配以下任意次数()
    • (?!et)
      反向前瞻确保后续内容与
      et
      字面上不匹配
    • [^,]
      按字面意思匹配除逗号以外的任何字符
  • inc\.
    Match
    inc.
选择2
  • (?:et |,)
    按字面意思匹配
    et
    或逗号
  • [^,]*?
    匹配集合中不存在的任何字符(除逗号以外的任何字符
    任意次数,但尽可能少)
  • ([\p{Lu}\p{N}][^,]*?\s(?:inc\.| sons | ltd.))
    将以下内容捕获到捕获组1中
    • [\p{Lu}\p{N}]
      匹配任何Unicode大写字符或Unicode数字(用于数字公司)
    • [^,]*?
      匹配集合中不存在的任何字符(除逗号以外的任何字符
      任意次数,但尽可能少)
    • \s
      匹配空白字符
    • (?:inc\.| sons | ltd\)
      匹配以下任一项
      • inc\.
        Match
        inc.
      • sons
        Match
        sons
      • ltd\.
        Match
        ltd.

笔记 正则表达式模块vs re 通过使用模块,我们可以使用Unicode字符类,如
\p{Lu}
,以确保我们还可以发现公司名称以大写Unicode字符开头的可能性,如
É

抓住特殊情况 正则表达式链接(在“代码”下)包括要测试的附加字符串:

, Étoile Simpsons et sons, Étoile Simpsons inc., Étoile et Simpsons inc.
添加此附加行时,只应捕获以下字符串(根据OP规范的有效公司名称):

  • 辛普森父子公司
  • 爱多乐辛普森公司
  • 爱多乐辛普森有限公司
这带来了一些挑战,包括:

  • 公司名称以大写Unicode字符
    É
    开头。
    • 这意味着我们必须确保Unicode大写字母的兼容性,因此使用类似
      [A-Z]
      的方法来确保名称以大写字符开头是不可能的
  • 公司以
    子公司
    结尾,但也包括
    子公司
    (子公司不能在第一次匹配时停止)。
    • 以《辛普森一家》为例。
      • 这不应该以《辛普森一家》中的《儿子》
结尾。这是一种本能(至少在正则表达式中是如此)可能是使用
\b
来声明单词边界。虽然这可能是首选方法,但在这种情况下不起作用。以法语单词
blésons
为例。使用
\b
实际上将在
blésons
中匹配,因为正则表达式引擎很少匹配
\b
(?:et|,)[^,]*?\K[\p{Lu}\p{N}][^,]*?\s(?:inc\.|sons|ltd\.)
              ^^
Asphalte Vrac Transport inc.
9163-6704 Québec inc.
Entreprise Denis Dupré inc.
Gestion Jean M. Machado inc.
Impact Technologie Environnementale inc.
Les entreprises Luc Clément inc.
Transport Vrac Globe International inc.
, Étoile Simpsons et sons, Étoile Simpsons inc., Étoile et Simpsons inc.
aa = [s.strip() for s in text.split(',') if s.lower().endswith(' inc.')]
   >>> string = """En effet, Revenu Québec avait des motifs raisonnables de croire que ces entreprises avaient utilisé de fausses factures provenant de plusieurs sociétés, dont Asphalte Vrac Transport inc., 9163-6704 Québec inc., Entreprise Denis Dupré inc., Gestion Jean M. Machado inc., Impact Technologie Environnementale inc., Les entreprises Luc Clément inc. et Transport Vrac Globe International inc."""
   >>> pattern = r'((?:[A-Z0-9\-]\.?\w*\s?(?:[a-z0-9\-]\w*\s?)?)+ inc\.)'
   >>> m = re.findall(pattern, string)
   >>> print('\n'.join(m))

   Asphalte Vrac Transport inc.
   9163-6704 Québec inc.
   Entreprise Denis Dupré inc.
   Gestion Jean M. Machado inc.
   Impact Technologie Environnementale inc.
   Les entreprises Luc Clément inc.
   Transport Vrac Globe International inc.
   [A-Z0-9\-] # match an uppercase letter or number or dash
   \.?        # match optional dot
   \w*        # match alpha-numeric chars 0 or more times
   \s?        # match optional white-space

   (?:[a-z0-9\-]\w*\s?)? # same again except with lowercase letters
                         # the ? means 0 or 1 times

    inc\.     # match ' inc.'
   (?: ... )  # non-capturing group
   ( ... )    # capturing group (whole thing)
   x?          # match x optional
   x*          # in this case match x 0 or more times
   x+          # match x 1 or more times
re.findall(r"\b[A-Z0-9](?:\w|-)*\s+(?:(?:\w|-)+\s+)*inc\.", text)
re.findall(r"\b[A-Z0-9](?:\w|-)*\s+(?:(?:\w|-)+\s+)*(?:[Ii]nc?|[Ll]td|[Ss]ons)(?:\.|\b)?", text)