Maybe,
^(?!.*opt3)filename\.txt
might simply suffice.
Just in case, filename.txt
wouldn't be at the beginning of the string, then
^(?!.*opt3).*(filename\.txt)
would be an option to look into, as well.
RegEx Circuit
jex.im visualizes regular expressions:

Test 1
import re
string = '''
filename.txt opt1 opt2 opt4
filename.txt opt1 opt2 opt3 opt4
filename.txt opt1 opt2 opt4
filename.txt opt1 opt2 opt3 opt4
'''
expression = r'^(?!.*opt3).*(filename\.txt)'
print(re.findall(expression, string, re.M))
Output 1
['filename.txt', 'filename.txt']
Test 2
If you wanted to swipe the entire string, you can simply add a .*
at the end of the expression:
import re
string = '''
filename.txt opt1 opt2 opt4
filename.txt opt1 opt2 opt3 opt4
filename.txt opt1 opt2 opt4
filename.txt opt1 opt2 opt3 opt4
'''
expression = r'^(?!.*opt3).*filename\.txt.*'
print(re.findall(expression, string, re.M))
Output 2
['filename.txt opt1 opt2 opt4', ' filename.txt opt1 opt2 opt4']
Test 3
import re
string = '''
filename.txt opt1 opt2 opt4
filename.txt opt1 opt2 opt3 opt4
filename.txt opt1 opt2 opt4
filename.txt opt1 opt2 opt3 opt4
'''
expression = r'(?m)^(?!.*opt3).*filename\.txt.*'
print(re.findall(expression, string))
for item in re.finditer(expression, string):
print(item.group(0))
Output
['filename.txt opt1 opt2 opt4', ' filename.txt opt1 opt2 opt4']
filename.txt opt1 opt2 opt4
filename.txt opt1 opt2 opt4