regex - 负表达式匹配

regex - negative expression matching

问题介绍

所以我绞尽脑汁试图让消极的表情 ahead/behinds 发挥作用。对于最后一个示例输入,我当前的解决方案 returns 不匹配(请参阅预期输出 table)。当 title 包含不在字符串末尾的年份时,我正在努力匹配字符串的部分。需要明确的是,我只对匹配位于字符串末尾的 year 感兴趣。当前正则表达式在最后一个示例中失败,因为它匹配 title 中的 NOT("Q" OR "\d*")。但是,我只希望它匹配 NOT("Q" AND "\d{1}")。任何 tips/suggestions 非常感谢。注意使用 Python 3.8.

示例输入

AXP - Earnings call Q2 2021
AXP - Conference call 2021
BAC,BAC.PE,BAC.PL,BACRP,BML.PL,BML.PJ,BML.PH,BML.PG,BAC.PB,BAC.PK,BAC.PM,BAC.PN - Earnings call Q2 2021
GM - General Motors Company (GM) Presents at Deutsche Bank AutoTech Conference
AXP - American Express Company (AXP) Management Presents at Barclays 2020 Global Financial Services Conference

period 将始终采用 Q[1-4] 的形式。 periodyear 是可选的。如果确实出现,它们将位于字符串的末尾。 symboltitle 总是被 - 分隔并且总是出现。

预期输出

symbol title period year
AXP Earnings call Q2 2021
AXP Conference call 2021
BAC Earnings call Q2 2021
GM General Motors Company (GM) Presents at Deutsche Bank AutoTech Conference
AXP American Express Company (AXP) Management Presents at Barclays 2020 Global Financial Services Conference

我试过的

r"^(?P<symbol>[^\,]{1,8})(\,[A-Z\.]+)*\s\-\s(?P<title>[^Q\d]*)\s?(?P<period>Q\d)?\s?(?P<year>19|20\d{2})$"

你可以使用

^(?P<symbol>[^,]{1,8})(?:,[A-Z.]*)*\s+-\s+(?P<title>(?:(?!Q\d).)*?)\s*(?P<period>Q\d)?\s?(?P<year>(?:19|20)\d{2})?$

参见regex demo

:

  • [^Q\d]* 是错误的,因为它匹配除 Q 和数字以外的任何零个或多个字符,您需要匹配任何文本直到 Q + 数字,即,一个 (?:(?!Q\d).)*? 脾气暴躁的代币
  • (?P<year>19|20\d{2})是必须的,但是必须是可选的,而且19|20没有分组,所以\d{2}只适用于20(?P<year>19|20\d{2})= > (?P<year>(?:19|20)\d{2})?.

这里还有其他小的改进。

详情:

  • ^ - 字符串开头
  • (?P<symbol>[^,]{1,8}) - 组“符号”:逗号以外的一到八个字符
  • (?:,[A-Z.]*)* - 零次或多次重复逗号,然后零次或多次大写 letters/dots
  • \s+-\s+ - 用一个或多个空格括起来的连字符
  • (?P<title>(?:(?!Q\d).)*?) - 组“标题”:除换行符以外的任何字符,零个或多个但出现次数尽可能少,不会开始 Q+ 数字字符序列
  • \s* - 零个或多个空格
  • (?P<period>Q\d)? - 组“句点”:一个 Q 和一个数字
  • \s? - 一个可选的空格
  • (?P<year>(?:19|20)\d{2})? - 一个可选的组“年”:1920 然后两位数
  • $ - 字符串结尾。