Parsing with multiple loops opening files
<p>I'm trying to count the number of lines contained by a file that looks like this:</p>

<pre><code>-StartACheck
---Lines--
-EndACheck
-StartBCheck
---Lines--
-EndBCheck
</code></pre>

<p>with this:</p>

<pre><code>count=0
z={}
for line in file:
      s=re.search(r'\-+Start([A-Za-z0-9]+)Check',line)
      if s:
           e=s.group(1)
           for line in file:
               z.setdefault(e,[]).append(count)
               q=re.search(r'\-+End',line)
               if q:
                   count=0
                   break

for a,b in z.items():
    print(a,len(b))
</code></pre>

<p>I want to basically store the number of lines present inside ACheck , BCheck etc in a dictionary but I keep getting the wrong output</p>

<p>Something like this</p>

<pre><code>A,15
B,9
</code></pre>

<p>etc</p>

<p>I found out that even though the code should work, it doesn't because of the way the file is opened. I can't change the way it is opened and was looking for an implementation that only opens the file once but counts the same things and gives the exact same output without all the added functions of the newer python version. </p>

<p>This kind of problem can be resolved with a <a href="https://en.wikipedia.org/wiki/Finite-state_machine" rel="nofollow">finite state machine</a>. This is a complex matter that would need more explanation than what I could write here. You should look into it to further understand what you can do with it. </p>

<p>But first of all, I'm going to do a few presumptions:</p>

<ul>
<li>The input file doesn't have any errors</li>
<li>If you have more than one section with the same name, you want their count to be combined</li>
<li>Even though you have tagged this question python 2.7, because you are using <code>print()</code>, I'll presume you are using python 3.x</li>
</ul>

<p>Here's my suggestion:</p>

<pre><code>import re

input_filename = "/home/evens/Temporaire/StackOverflow/Input_file-39339007.txt"

matchers = {
    'start_section' : re.compile(r'\-+Start([A-Za-z0-9]+)Check'),
    'end_section' : re.compile(r'\-+End'),
    }

inside_section = False          # Am I inside a sectionÂ ?
section_name = None             # Which section am I inÂ ?
tally = {}                      # Sums of each section

with open(input_filename) as file_read:
    for line in file_read:

        line_matches = {k: v.match(line) for (k, v) in matchers.items()}

        if inside_section:
            if line_matches['end_section']:
                future_inside_section = False
            else:
                future_inside_section = True
                if section_name in tally:
                    tally[section_name] += 1
                else:
                    tally[section_name] = 1
        else:
            if line_matches['start_section']:
                future_inside_section = True
                section_name = line_matches['start_section'].group(1)

        # Just before we go in the future
        inside_section = future_inside_section   

for (a,b) in tally.items():
    print('Total of all "{}" sections: {}'.format(a, b))
</code></pre>

<p>What this code does is determine :</p>

<ul>
<li>How it should change its state (Am I going to be inside or outside a section on the next line?)</li>
<li>What else should be done:

<ul>
<li>Change the name of the section I'm inÂ ?</li>
<li>Count this line in the present sectionÂ ?</li>
</ul></li>
</ul>

<p>But even this code has its problems:</p>

<ul>
<li>It doesn't check to see if a section start has a matching section end (<code>-StartACheck</code> could be ended by <code>-EndATotallyInvalidCheck</code>)</li>
<li>It doesn't handle the case where two consecutive section starts (or ends) are detected (Error? Nested sections?)</li>
<li>It doesn't handle the case where there are lines outside a section</li>
<li>And probably other corner cases. </li>
</ul>

<p>How you want to handle these cases is up to you</p>

<p>This code could probably be further simplified but I don't want to be too complex for now.</p>

<p>Hope this helps. Don't hesitate to ask if you need further explanations.</p>

python python-2.7