0

次のようなミドルネームに一致する正規表現があります。

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、DMD\n生まれ:\nオハイオ州アクロン\n大学:\n1998 年、ケニオン カレッジで学士号を取得

このパターンでは問題なく動作し、ミドル ネーム「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 は、式の動作を変更しないという意味で安全に使用できませんか? 英数字以外の文字の前にバックスラッシュを追加すると、一致しない可能性がありますか?

どんな助けでも大歓迎です!

4

1 に答える 1

1

すでに正規表現の特殊文字が含まれているものにre.escapeを使用すると、それらのリテラル文字が検索されます。

ここに2つの提案:

  1. 可能であれば、re.IGNORECASEケースに関係なく正規表現をテストするために使用してみませんか?

  2. そうでない場合は、このようなことを行うことができます

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) 

ここで引数をフォーマットする順序についてはわかりませんが、要点はわかります

于 2012-04-30T13:17:37.557 に答える