0

I have a file with lines which need to be repeated as many times as the decimal/hex value mentioned in the first line.

Input Example:

Loop  3  {Line1}  ##the line is within curly braces so I used regex but not printing it out right. 
Label: Blank {Line2}
Jump Label {Line3} 

Output Example:

Line1
Line2
Line3
Line2
Line3
Line2
Line3

My code so far:

line_1_ = re.compile(r'Loop\s*([0-9]+|0x[0-9a-fA-F]+)\s*\{(\w+)\}', re.DOTALL)
for match in line_1_.finditer(inputfileContents):
    looptimes =  int(match.group(1))
    line_1 = match.group(2)
    jump = re.search(r'Jump\s*(\w+)\s*\{(.*?)\}', inputfileContents, re.DOTALL)
    label = re.search(r'(\w+):\s*(\w+)\s*\{(\w+)\}', inputfileContents, re.DOTALL)
    for i in range(looptimes):
        if jump.group(1) == label.group(1):
            print '%s\n%s' % (label.group(3), jump.group(2))

Error: I cannot increment a line with line++. Which I understand as it is a string but not sure how to increment it otherwise.

Effectively it is just repeating Line2 and Line 3 3 times. But if there are multiple lines between the Jump and loop it has to print all the lines starting from Label statement to the jump statement including the jump statement.

This doesn't work if there are multiple lines between the jump and label statements...

Example 2:

Blank {Line0}
Loop  3  {Line1}  
Label: Blank {Line2}
       Blank {Line3}
       Blank {Line4}
Jump Label {Line5}
Blank {Line6}

Expected Output int he above case:

Line0
Line1
Line2
Line3
Line4
Line5
Line2
Line3
Line4
Line5
Line2
Line3
Line4
Line5
Line6

Example 3:

Blank  {Line0}
Loop 3 {Line1}
Label2 {Line2}
Blank  {Line3}
Loop 2 {Line4}  
Label1:{Line5}
Blank  {Line6}
Jump Label1 {Line7}
Blank  {Line8}
Jump Label2 {Line9}
Blank  {Line10}

Output I need:

Line0
Line1
Line2
Line3
Line4
Line5
Line6
Line7
Line5
Line6
Line7
Line8
Line9
Line2
Line3
Line4
Line5
Line6
Line7
Line5
Line6
Line7
Line8
Line9
Line2
Line3
Line4
Line5
Line6
Line7
Line5
Line6
Line7
Line8
Line9
Line10

I tried to implement @Samy Arous method from here: Using Python to Parse a File for Nested Loops but couldn't implement it so far.

Community
  • 1
  • 1
Doodle
  • 45
  • 2
  • 7
  • 3
    Welcome to Stack Overflow! It looks like you want us to write some code for you. While many users are willing to produce code for a coder in distress, they usually only help when the poster has already tried to solve the problem on their own. A good way to demonstrate this effort is to include the code you've written so far, example input (if there is any), the expected output, and the output you actually get (console output, tracebacks, etc.). The more detail you provide, the more answers you are likely to receive. Check the [FAQ] and [ask]. – Adam Smith Sep 29 '14 at 23:40
  • I should probably not use regex, but with ragex I can check for each part of the line .. I dint post it earlier because my code is not going the right direction... – Doodle Sep 29 '14 at 23:56
  • Is your output example what you want, or what you are getting? – Ethan Furman Sep 30 '14 at 00:31
  • I am getting that output right now. But I need to change this so that it is able to print out multiple lines between Jump and Label.. Right now if I add couple lines between the two statements my code will break. – Doodle Sep 30 '14 at 00:35
  • I have edited including the possible input for which my code is not working.. – Doodle Sep 30 '14 at 00:39

2 Answers2

0

I found it easier without regex:

import sys

infile = sys.stdin

def extract(line):
    return line[line.find('{') + 1: line.rfind('}')]

for first in infile:
    if first.startswith('Loop '):
        break
    else:
        print extract(first)

count = int(first.split()[1])
lines = [extract(first)] + map(extract, infile)

while count > 0:
    print '\n'.join(lines)
    count -= 1
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • I used regex because these are not the only lines int he infile, it has many and I am matching those lines that are int his format.. – Doodle Sep 30 '14 at 01:51
  • OK well you can do that part by splitting the line and checking the first token (if it's Loop or Label or Jump etc.). I don't think you need regexes still. Anyway, all the example inputs you've posted so far work with the code I wrote above; perhaps you can add a more full example with expected output. – John Zwinck Sep 30 '14 at 02:27
  • Thanks yes it works. Could you suggest a link for the return statement you have used? I am trying to understand that.. – Doodle Sep 30 '14 at 04:37
  • I just return a "slice" of `line` by the expression `line[start:end]`, where `start` is the first character to include, i.e. one past the `{` and `end` is the first character to *exclude*, i.e. the final `}`. – John Zwinck Sep 30 '14 at 04:51
  • I just added a line for which this breaks. My file is huge and I have many different kinds of lines.. So processing each line as I read and when I read the Loop line I need to Loop the jump statement that many times – Doodle Sep 30 '14 at 06:30
  • @Doodle: I updated my answer to work for the new case you gave. Note that the original case printed the "Loop" line only once whereas the new one prints it multiple times; you can choose which way you want it, the answer now does the latter. – John Zwinck Sep 30 '14 at 07:00
  • Could we modify the map(extract, infile) to only take the lines until JUMP? If there is another line Blank {Line6}, then it also take that. But I need only the looping to be printed out.. I tried to give a condition for map but not sure how.. – Doodle Sep 30 '14 at 23:57
  • @ John Zwinck I followed Rafi Kamal's example from here : [link] (http://stackoverflow.com/questions/18865058/extract-values-between-two-strings-in-a-text-file-using-python ) and used it with John Zwinck 's answer too. I will post it soon. Thanks you very much John!!! – Doodle Oct 02 '14 at 01:44
0

This works when there are multiple loop statements in a file

import sys

inputtfile = sys.stdin
inputfileContents = open(r'path to input file')


def extract(line):
    return line[line.find('{') + 1: line.rfind('}')]

loopCount = 0
loopLines = []
inLoop = False
for line in inputfileContents:
    if line.startswith('Loop '):
        loopCount = int(line.split()[1])
    inLoop = True
    loopLines.append(extract(line))
    elif line.startswith('Jump '):
        loopLines.append(extract(line))
        for i in range(loopCount):
            for loopLine in loopLines:
                print loopLine

    #reset state variables to track next possible loop
    loopCount = 0
    inLoop = False
    loopLines = []
    elif inLoop:
        loopLines.append(extract(line))
    else:
        print extract(line)
Doodle
  • 45
  • 2
  • 7