decodebytes
decodebytes

Reputation: 421

Trouble matching empty line in conditional (python)

My code

for line in f:
    if re.match(r'#\s*' + cfgvalue, line):
        print "found it commented out"
    elif line.startswith(cfgvalue):
        print "found it"

I then want something to capture if the line is not there.

Sounds simple, but if I place in

elif not line.startswith(cfgvalue):
     print "not found"

It instead overrides the match section

elif line.startswith(cfgvalue)

So what would normally be a "found it", comes out as "not found"?

Complete code:

for line in f:
    if re.match(r'#\s*' + cfgvalue, line):
        print "found it commented out"
    elif line.startswith(cfgvalue):
        print "found it"
    else:
         if not line.startswith(cfgvalue):
             print "not found"

Upvotes: 0

Views: 68

Answers (2)

Hai Vu
Hai Vu

Reputation: 40773

There are two approaches I can think of. The first is to have a found boolean variable which starts out as False. If you found it, then set it to True:

found = False
for line in f:
    if re.match(r'#\s*' + cfgvalue, line):
        print 'found it commented out: {}'.format(line)
    elif line.startswith(cfgvalue):
        print 'found it: {}'.format(line)
        found = True

if found:
    print 'FOUND'
else:
     print 'NOT FOUND

Note: in the for loop, only set found to True. Do not set it to False, or its value will be incorrectly overwritten.

The second approach is a little bit more exotic. It relies on the fact that the for loop has an else clause, which will be activated if the loop ends without any break:

for line in f:
    if re.match(r'#\s*' + cfgvalue, line):
        print 'found it commented out: {}'.format(line)
    elif line.startswith(cfgvalue):
        print 'found it: {}'.format(line)
        break
else:
    print 'Not found:', cfgvalue

In this case, if we find cfgvalue, we will immediately break out of the for loop and the else clause will not be executed. If we don't find cfgvalue, then the for loop will exit without breaking, thus the else clause will execute.

Upvotes: 1

David Zemens
David Zemens

Reputation: 53663

First, check whether the value exists in the line. If it does, then do your pattern matching, then check the startswith, then check if it exists anywhere else.

https://repl.it/BZ4s/2 <-- you can test it, here

import re
from cStringIO import StringIO
f = StringIO("AAA - IamOK\n#AAA - IamCOMMENT\nIamOTHER\nAnother line AAA balgh")
cfgvalue = "AAA"

for line in f:
    if cfgvalue in line:
        if re.match(r'#\s*' + cfgvalue, line):
            print "found it commented out"
        elif line[:len(cfgvalue)] == cfgvalue:
            print "found it at start of line"
        else:
            print "found it at {}".format(line.index(cfgvalue))
    else:
        print "not found"

Results:

found it at start of line
found it commented out
not found
found it at 13

This may even help identify whatever specific problem, as I've added a case to check for this cfgvalue at any position in the line. Perhaps there is whitespace or non-printing characters in which case you might want to do:

for line in [l.strip() for l in f]:

Upvotes: 0

Related Questions