1

I have eliminated some of the nested loops for simplicity of the example.

I am iterating over a file line-by-line using fileinput. If the line meets a certain condition I want it to replace all future lines with '' until it meets the condition again.

import re
import fileinput
with fileinput.FileInput("survey.qsf", inplace=True, backup='.bak') as file:
    for line in file:
        if re.match(r'l'+datamap[i][2]+'.*$',line)!=None:
            line=re.sub(r'.*$','',line)
            while re.match(r'lQID\d*$',line)==None:
                line=re.sub(r'.*$','',line)
                next(line)

I used "next(line)" as a placeholder as I can't figure out how to iterate to the next line without breaking out of the inner loop.

I want to be able to iterate through the lines to have:

lQID44
xyz
xyz
lQID45

output as:

[blank line]
[blank line]
[blank line]
lQID45

Thanks.

3
  • 1st: i'd simply set a boolean variable to true or false when matching occurs and replace lines dependent on this variable. No nested loops. 2nd: i'd use str.startswith rather than re, as imo that would suit here too. However, perhaps i just didn't get the complicated point here.... Commented Jan 2, 2019 at 14:55
  • next(file) gives you the next line of the iterator. Beware that using it like this can lead to a StopIteration exception, if there is no next line, so maybe you should guard your call of next with a try-except-block, if you cannot make sure that there will always be a next line. Commented Jan 2, 2019 at 14:55
  • I didn't know about str.startswith I just got into the habit of using re. Yeah I am finding that iterating with next(file) leads to a StopIteration exception I'll catch that and then it should work. Thanks all. Commented Jan 2, 2019 at 15:15

1 Answer 1

4

next takes the iterator as its argument.

while re.match(r'lQID\d*$',line)==None:
    line=re.sub(r'.*$','',line)
    try:
        line = next(file)  # Not next(line)
    except StopIteration:
        break

As an aside, there's no need to use re.sub to replace the entire line with an empty string; line = '' would suffice.

(Also, assigning to line doesn't make changes to the actual file; inplace=True just means that you can write to file as well as read from it, but you have to explicitly write to the file, using print or file.write.)

Sign up to request clarification or add additional context in comments.

3 Comments

Hi, thanks for that. I think that "next()" might have a slight issue iterating fileinput because I get a StopIIteration error even though it isn't the last line when next(file) is used. Thanks for the other explanations though as this project is bigger than I had anticipated and my programming needs some finesse!
I forgot to mention that you need to reassign its return value to line so that you are checking the new line, rather than the same previous line over and over again. But it is true that calling next explicitly requires you to catch StopIteration your self when you do reach the end of the file, unlike the for loop which catches it for you (in addition to calling next for you implicitly).
Brilliant, thanks again mate. Thanks for simplifying my code whilst you were at it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.