re.escape修改行为

时间:2012-04-30 12:58:16

标签: python regex

我有一个正则表达式来匹配看起来像这样的中间名:

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是安全的吗?在非字母数字字符之前添加反斜杠会导致它不匹配的原因是什么?

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

在已包含正则表达式特殊字符的内容上使用re.escape将查找 literal 字符。

这里有两条建议:

  1. 如果可能的话,为什么不使用re.IGNORECASE来测试正则表达式而不管情况如何?

  2. 如果没有,你可以做这样的事情

  3. 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的顺序,但是你明白了