You can use a negative lookahead statement to require that it is $not followed by a trailing newline:
>>> re.match(r'\w+$(?!\n)', 'foo\n')
>>> re.match(r'\w+$(?!\n)', 'foo')
<_sre.SRE_Match object; span=(0, 3), match='foo'>
re.MULTILINE ; OP , . , $ :
[ re.MULTILINE], '^' ( ); '$' ( ). '^' '$' ( ) .
, re.X.