我有一个正则表达式来匹配看起来像这样的中间名:
first_name = 'Matthew'
last_name = 'Walsh'
for char in first_name:
new_first_name+='(' + char.lower() + '|' + char.upper() + ')'
for char in last_name:
new_last_name+='(' + char.lower() + '|' + char.upper() + ')'
middle_name_regex_str = "\b?((" + new_first_name + " (?P<middle_name1>[A-Z][^ ]?[a-z]* )?" + new_last_name + ")|(" + new_last_name + " (?P<middle_name2>[A-Z][^ ]?[a-z]* )?" + new_first_name + "))"
这是一个适用于的模式:
MATTHEW B. WALSH,D.M.D。\ nBorn:\ nAkron,Ohio \ nCollege:\ n 艺术,肯扬学院,1998年
对于这种模式,它工作正常,并匹配中间名称'B。'
但是我想要安全并且逃避名字和姓氏,但是当我添加re.escape
时它失败了:
middle_name_regex_str = "\b?((" + re.escape(new_first_name) + " (?P<middle_name1>[A-Z][^ ]?[a-z]* )?" + re.escape(new_last_name) + ")|(" + re.escape(new_last_name) + " (?P<middle_name2>[A-Z][^ ]?[a-z]* )?" + re.escape(new_first_name) + "))"
现在正则表达式不匹配:
regex = re.compile(middle_name_regex_str)
regex.search('MATTHEW B. WALSH, D.M.D.\nBorn:\nAkron, Ohio\nCollege:\nBachelor of Arts, Kenyon College, 1998')
这不会返回任何内容。
在不改变表达式行为的意义上,不应该使用re.escape是安全的吗?在非字母数字字符之前添加反斜杠会导致它不匹配的原因是什么?
任何帮助将不胜感激!
答案 0 :(得分:1)
在已包含正则表达式特殊字符的内容上使用re.escape将查找 literal 字符。
这里有两条建议:
如果可能的话,为什么不使用re.IGNORECASE
来测试正则表达式而不管情况如何?
如果没有,你可以做这样的事情
first_name= 'Matthew'
last_name = 'Walsh'
first_name_re = "".join('(%s|%s)' % (re.escape(c.upper()),re.escape(c.lower())) for c in first_name)
last_name_re = "".join('(%s|%s)' % (re.escape(c.upper()),re.escape(c.lower())) for c in last_name)
# now that they are safe -we can simply put them in the middle of the regex
middle_name_regex_str = "\b?((%s (?P<middle_name1>[A-Z][^ ]?[a-z]* )?%s)|(%s (?P<middle_name2>[A-Z][^ ]?[a-z]* )?%s))" % (first_name_re, last_name_re, first_name_re, last_name_re)
不确定格式化args的顺序,但是你明白了