使用正则表达式

时间:2018-10-07 06:50:13

标签: python regex python-3.x

我正努力拒绝用换行符分隔的单词的匹配。

这是测试字符串:

Cardoza Fred
Catto, Philipa
Duncan, Jean
Jerry Smith
and
but
and
Andrew

Red 
Abcd

DDDD

正则表达式规则:

1)如果一个单词后跟逗号,则拒绝它。因此,我们将删除Catto。

2)仅选择以大写字母开头的单词。因此,and等将被删除

3)如果单词后面有回车符(即是名字,请忽略它)。

这是我的尝试:\b([A-Z][a-z]+)\s(?!\n)

说明:

\b                #start at a word boundary
([A-Z][a-z]+)     #start with A-Z followed by a-z
\s                #Last name must be followed by a space character
(?!\n)            #The word shouldn't be followed by newline char i.e. ignore first names. 

我的正则表达式有两个问题。

1) AndrewAndre匹配。我不确定为什么错过了w。我还观察到,如果我更改示例文本的底部部分以删除所有字符(包括安德鲁的w及之后的字符),Andrew中的w不会被遗漏。即示例文本如下所示:

Cardoza Fred
Catto, Philipa
Duncan, Jean
Jerry Smith
and
but
and
Andrew

输出应为:

Cardoza 
Jerry

您可能会问:为什么Andrew被拒绝?这是由于两个原因:a)Andrew后没有空格。 b)没有first_name "space" last_name组合。

2)正在使用我的正则表达式选择名字。如何忽略名字?

我研究了SO。似乎有类似的线程ignoring newline character in regex match,但答案并未涉及忽略\r

此问题改编自Watt的Beginning Regex书。我在这个问题上花了将近1个小时,但没有成功。任何解释将不胜感激。我正在使用python的re模块。

这里是regex101供参考。

1 个答案:

答案 0 :(得分:1)

Andre(而不是尾随的w)在您的正则表达式中匹配,因为最后一个标记是\n的负前瞻,并且在此之前是 optional < / em>空间。因此,Andrew<end of line>由于位于行尾而失败,因此引擎回溯到Andre,成功了。

也许regex101中\s?中的可选量词是一个错字,但从头开始可能会更容易。如果要查找以空格开头的名字,然后是另一个名字,则可以使用

^[A-Z][a-z]+(?= [A-Z][a-z]+$)

带有m标志:

https://regex101.com/r/kqeMcH/5

m标志允许^匹配行的开头,$匹配行的结尾-比查找\n更容易s。 (没有m标志,^将只匹配 string 的开头,而$同样将只匹配 string < / em>)

也就是说,从重复的字母字符开始,然后向前寻找空格和更多字母字符,然后是该行的结尾。对于换行符等,使用正向先行要比负向先行容易得多。

请注意,在正则表达式中,文字空间\s更可靠,因为\s任何空格字符匹配,包括换行符。如果您要查找文字空间,最好使用文字空间。

要在Python正则表达式中使用标志,请使用flags=,或在模式的开头定义标志,例如

pattern = r'(?m)^[a-z]+(?= [A-Z][a-z]+$)'