Issue in storing regexp of multiple lines in python
Question: I am having the following pattern in text file

    
    
    Question1: Quesion XYZ
    a. option1
    b. option2
    c. option3
    d. option4
    
    Question2 : Question next
    a. option1
    b. option2
    c. option3
    d. option4
    
    so on multiple questions
    

This pattern is there in the text file. I am trying to read the text file and
segregate each question and respective choices. I want the output as

    
    
    Block1 :
    
      Question1: Quesion XYZ
        a. option1
        b. option2
        c. option3
        d. option4
    
    Block 2 :     
        Question2 : Question next
        a. option1
        b. option2
        c. option3
        d. option4
    

Motive is to retrieve each question and respective options. I was trying for a
`list` which I will append each question and respective options. I will create
multiple lists where I will store each question

I have done coding like

    
    
    import re
    txt = open("questions.txt")
    i = 0 ; 
    for line in txt:
        key = 'list' + str(i)
        key = []
        # if line == "\n" : continue
        if re.search("^\n", line): continue
        searchObj = re.search("([\d]+)\.\s*(.*)", line)
        if searchObj : 
            i = searchObj.group(1)
            key = searchObj.group(2)
        searchObj2 = re.search("[\w]+\.\s*(.*)", line)
        if searchObj2 : 
            key.append = (searchObj2.group(1))
    
    txt.close()
    print alist1
    

It is giving error. Moreover it is not solving the above purpose. I heard that
we can also use dict for that. Need to know how as there can be `n` number of
questions in the file.


Answer: Here is a generic method to solve this case, I said generic because it needs
to be modified within the content of your text file and how it is formatted,
which means tweaking the `re` expressions, anyways, what I would do, is a
create a list of dictionaries, with each dictionary holding data of each
question, as follows:

    
    
    >>> import re
    >>>
    >>> patQNbBody = re.compile('(?P<QNb>Question\\d+)\\s*:\\s*(?P<QBody>[\\w\\s]+)$', re.IGNORECASE|re.MULTILINE|re.DOTALL)
    >>>
    >>> patQopt = re.compile('^[a-z]\\.\\s*(?P<Opt>\\w+)$', re.IGNORECASE|re.MULTILINE|re.DOTALL)
    >>>
    >>> my_questions = []
    >>> 
    >>> with open('questions.txt', 'r') as f:
            i = -1
            for line in f:
                m1 = patQNbBody.search(line)
                if m1:
                    i += 1
                    p = m1.group(1)
                    my_questions.append({'Number':m1.group(1), 'Body':m1.group(2), 'options':[]})
                else:
                    m2 = patQopt.search(line)
                    if m2:
                        my_questions[i]['options'].append(m2.group(1))
    
    >>> my_questions
    [{'options': ['option1', 'option2', 'option3', 'option4'], 'Number': 'Question1', 'Body': 'Quesion XYZ\n'}, {'options': ['option1', 'option2', 'option3', 'option4'], 'Number': 'Question2', 'Body': 'Question next\n'}]
    

If order matters to you, then you can get the advantage of
[`OrderedDict`](https://docs.python.org/3/library/collections.html#collections.OrderedDict)
to your best:

    
    
    >>> import re
    >>> from collections import OrderedDict
    >>>
    >>> patQNbBody = re.compile('(?P<QNb>Question\\d+)\\s*:\\s*(?P<QBody>[\\w\\s]+)$', re.IGNORECASE|re.MULTILINE|re.DOTALL)
    >>>
    >>> patQopt = re.compile('^[a-z]\\.\\s*(?P<Opt>\\w+)$', re.IGNORECASE|re.MULTILINE|re.DOTALL)
    >>>
    >>> my_questions = []
    >>> with open('test1.txt', 'r') as f:
            i = -1
            for line in f:
                d = OrderedDict()
                m1 = patQNbBody.search(line)
                if m1:
                    i += 1
                    for k,v in zip(('Number','Body','Options'),(m1.group(1), m1.group(2), [])):
                        d[k] = v
                    my_questions.append(d)
                else:
                    m2 = patQopt.search(line)
                    if m2:
                        my_questions[i]['Options'].append(m2.group(1))
    
    >>> my_questions
    [OrderedDict([('Number', 'Question1'), ('Body', 'Quesion XYZ\n'), ('Options', ['option1', 'option2', 'option3', 'option4'])]), OrderedDict([('Number', 'Question2'), ('Body', 'Question next\n'), ('Options', ['option1', 'option2', 'option3', 'option4'])])]
    >>> 
    >>> 
    >>> my_questions[0]['Number']
    'Question1'
    >>> my_questions[1]['Body']
    'Question next\n'
    >>> 
    >>> my_questions[1]['Options']
    ['option1', 'option2', 'option3', 'option4']
    >>> 
    

