我正努力拒绝用换行符分隔的单词的匹配。
这是测试字符串:
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) Andrew
与Andre
匹配。我不确定为什么错过了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供参考。
答案 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]+$)'