我正试图从新闻稿中提取公司名称。例如,下面有一个新闻稿的片段(法语),其中包含以.inc
结尾的七家公司的列表。
En effet,RevenuQuébecavait des motifs raisonnables de croire que ces entreprisesavaientutilisédefausses factures provenant deplusieurssociétés,dont Asphalte Vrac Transport inc。, 9163-6704 Québecinc。, EntrepriseDenisDupréinc。, Gestion Jean M. Machado inc。, Impact Technologie Environnementale inc。,< strong> Les entreprisesLucClémentinc。 et Transport Vrac Globe International inc。
我正在尝试使用以下代码提取所有名称:
aa = re.findall('inc\.,? (.*?inc\.)', text)
我设法捕获了不少,但由于某种原因我无法想象,我无法全部提取它们。这似乎是微不足道的,但它已经让我踩了几个小时....
感谢任何帮助!
答案 0 :(得分:5)
使用regex模块(而非re
),您可以使用此解决方案。
这是原始正则表达式,仅匹配inc.
。这也不允许包含et
的公司名称。有关更全面的正则表达式,请参阅选项2 。
[\p{Lu}\p{N}](?:(?!et)[^,])*inc\.
对于更全面的正则表达式,还会检查其他公司实体,例如ltd.
或sons
,您可以使用以下正则表达式。
(?:et|,)[^,]*?([\p{Lu}\p{N}][^,]*?\s(?:inc\.|sons|ltd\.))
注意:在某些版本的正则表达式中,您可以使用\K
令牌。此标记重置报告的匹配的起始点(任何以前消耗的字符不再包含在最终匹配中)。如果您的正则表达式引擎支持\K
令牌(并且不将其转换为文字K
),则可以使用以下内容(实际上无需捕获组)。
(?:et|,)[^,]*?\K[\p{Lu}\p{N}][^,]*?\s(?:inc\.|sons|ltd\.)
^^
En effet,RevenuQuébecavaitdes motifs raisonnables de croire que ces entreprisesavaientutilisédefausses factures provenant de plusieurssociétés,dont Asphalte Vrac Transport inc。,9163-6704 Québecinc。,EntrepriseDenisDupréinc。,Gestion Jean M. Machado inc。,Impact Technologie Environnementale inc。,Les entreprises Luc 克莱门特公司et Transport Vrac Globe International inc。
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.
[\p{Lu}\p{N}]
匹配集合中的任何内容(在本例中为\p{Lu}
- 任何语言中的任何大写字符(包括用于大写法语字符的Unicode和用于数字公司的数字)(?:(?!et)[^,])*
符合以下任意次数(tempered greedy token)
(?!et)
否定前瞻确保后续内容与et
字面上不匹配[^,]
匹配除逗号,
之外的任何字符inc\.
按字面意思匹配inc.
(?:et|,)
字面匹配et
或逗号,
[^,]*?
匹配集合中不存在的任何字符(除逗号,
之外的任何字符,但会尽可能少([\p{Lu}\p{N}][^,]*?\s(?:inc\.|sons|ltd\.))
将以下内容捕获到捕获组1中
[\p{Lu}\p{N}]
匹配任何Unicode大写字符或Unicode编号(对于数字公司)[^,]*?
匹配集合中不存在的任何字符(除逗号,
之外的任何字符,但会尽可能少\s
匹配空白字符(?:inc\.|sons|ltd\.)
匹配以下任一项
inc\.
按字面意思匹配inc.
sons
按字面意思匹配sons
ltd\.
按字面意思匹配ltd.
使用regex模块允许我们使用Unicode字符类,例如\p{Lu}
,以确保我们也能够发现公司名称以大写Unicode字符开头的可能性,例如É
。
正则表达式链接(在代码下)包含一个要测试的附加字符串:
, Étoile Simpsons et sons, Étoile Simpsons inc., Étoile et Simpsons inc.
添加此附加行后,只应捕获以下字符串(根据OP的规范,有效的公司名称):
Étoile Simpsons et sons
Étoile Simpsons inc.
Étoile et Simpsons ltd.
这提出了一些挑战,包括:
É
开头。
[A-Z]
的内容无法确保名称以大写字母开头。sons
结尾,但也包含sons
(sons
的首次匹配时无法停止)。
Étoile Simpsons et sons
为例。
sons
的{{1}}结束。天生的本能(至少在正则表达式中)可能是使用Simpsons
来断言单词边界。尽管这可能是首选方法,但在这种情况下它不起作用。以法语单词\b
为例。使用blésons
实际上会在\b
中匹配,因为即使启用了blésons
标记,正则表达式引擎也很少与Unicode字符匹配\b
(这就是我使用u
的原因代替)。\s
字样(在句子sons
中)。它不得超越公司名称的结尾。
Their sons et sons, les sons.
。让它变得懒惰将允许它在第一场比赛时停止而不是匹配整个句子错误。.*?
包含有效公司名称的所有部分(以大写字母开头的单词,后跟单词Their sons et sons, les sons.
),但这不应该匹配,因为它不是公司名称。
sons
,我使用它来确定什么是公司名称。答案 1 :(得分:1)
这种模式似乎可以解决问题:
>>> 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
答案 2 :(得分:0)
在这种情况下,您可以避免使用regex
,而是尝试:
text.split(“,”)
然后遍历创建的list
并查找".inc"
。
答案 3 :(得分:0)
aa = [s.strip() for s in text.split(',') if s.lower().endswith(' inc.')]
答案 4 :(得分:0)
由于答案已被接受,所以迟到了派对,但无论如何,这是一个使用Python的内置re
模块而不是第三方regex
模块的解决方案。
您的尝试正确地将公司名称的末尾锚定在 inc。上,但您需要某种方法来捕获名称的 start 。让我们将公司名称定义为:
此外,我们将一个单词定义为一串字母和/或数字,可能包含一个或多个连字符。通常我们会使用\w
来表示单词字符,但不包括连字符,所以我们需要单独匹配。
所以:
[A-Z0-9](?:\w|-)*
(?:\w|-)+
inc\.
单词由空格分隔,我们将其表示为\s+
。因此,对于#2的“可选的一个或多个单词”,我们必须创建一个包含一个或多个单词字符(包括连字符)后跟一个或多个空格字符的组,并重复该组零次或多次:(?:(?:\w|-)+\s+)*
< / p>
所以,把它们放在一起并在开始时添加\b
,确保它以一个完整的单词开头:
re.findall(r"\b[A-Z0-9](?:\w|-)*\s+(?:(?:\w|-)+\s+)*inc\.", text)
要扩展此功能,您还可以捕获以 Ltd。或 Sons 结尾的名称,并同时捕获大写的 Inc。并制作句点可选的:
re.findall(r"\b[A-Z0-9](?:\w|-)*\s+(?:(?:\w|-)+\s+)*(?:[Ii]nc?|[Ll]td|[Ss]ons)(?:\.|\b)?", text)