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]
的形式。 period
和 year
是可选的。如果确实出现,它们将位于字符串的末尾。 symbol
和 title
总是被 -
分隔并且总是出现。
预期输出
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})?
- 一个可选的组“年”:19
或 20
然后两位数
$
- 字符串结尾。
问题介绍
所以我绞尽脑汁试图让消极的表情 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]
的形式。 period
和 year
是可选的。如果确实出现,它们将位于字符串的末尾。 symbol
和 title
总是被 -
分隔并且总是出现。
预期输出
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})?
- 一个可选的组“年”:19
或20
然后两位数$
- 字符串结尾。