Using Regex to replace each instance of a match with a different string

I am currently working through "Automate Boring Things with python". I am participating in a hands-on project for Chapter 8 called Faces of Madness. The task is as follows:

Create a Mad Libs program that reads the fles text and allows the user to add their own text anywhere the word ADJECTIVE, NOUN, ADVERB or VERB appears in the text file. For example, a text flip might look like this:

The ADJECTIVE panda walked to the NOUN and then VERB. A nearby NOUN was unaffected by these events.

      

The program will find these occurrences and prompt the user to replace them.

Enter adjective: stupid

Enter a noun: chandelier

Enter the verb: screamed

Enter the noun: pickup

Then the following text file will be created:

The silly panda walked to the chandelier and then screamed. A nearby pickup truck was unaffected by these events.

      

The results should be printed on the screen and saved in a new text file.

My current program looks like this:

#! python3
# Requests user for an ADJECTIVE, NOUN, ADVERB, and a NOUN
# Replaces the words ADJECTIVE/NOUN/ADVERB/NOUN with the input in a txt file
# Saves the new Mad Lib as a new txt file

import re

reADJECTIVE = re.compile(r'''(ADJECTIVE)''')
reNOUN = re.compile(r'''(NOUN)''')
reVERB = re.compile(r'''(VERB)''')

for i in range(1):
    # Gets user input for ADVECTIVE/NOUN/VERB/NOUN
    ADJECTIVE = input('Enter an adjective: ')
    NOUN = input('Enter a noun: ')
    VERB = input('Enter a verb: ')
    NOUN2 = input('Enter a noun: ')

    madLibFile = open('madlib%s.txt' % (i + 1))
    madLibFileContent = madLibFile.read()
    madLibFile.close()
    madLibFileContent = madLibFileContent.split('. ')
    print(madLibFileContent)

    newMadLib = re.sub(reADJECTIVE, ADJECTIVE, madLibFileContent[0])
    newMadLib = re.sub(reNOUN, NOUN, newMadLib)
    newMadLib = re.sub(reVERB, VERB, newMadLib)
    newMadLib = newMadLib + '. ' + re.sub(reNOUN, NOUN2, madLibFileContent[1])

    print(newMadLib)

      

For this example, this program works, however due to the fact that I split the file it reads with fullstop / period, it only works when the input file format is:

ADJECTIVE NOUN ADVERB. NOUN.

and won't work for any other format like:

ANNOUNCEMENT NOUN. ADVERB NOUN.

My initial idea was to use a regex pattern:

(ADJECTIVE).*(NOUN).*(VERB).*(NOUN)

      

This works if we assume that any given Mad Lib follows the same adjective-noun-noun pattern.

If I were to use:

re.sub(r'(NOUN)', replacement, someString)

      

It will replace any NOUN instance on the replacement string. Can you replace each capture group with something else?

Thanks for your time and I hope the question was clear enough :)

+3


source to share


2 answers


The trick is to use a function instead of the replace string in re.sub

. Here's a rough way to do it.

import re

sentence = 'The ADJECTIVE panda walked to the NOUN and then VERB. A nearby NOUN was unaffected by these events.'

def consider(matchobj):
    content = matchobj.group()
    if content in ['NOUN', 'ADJECTIVE', 'ADVERB', 'VERB']:
        return input('Please enter ' + content)
    else:
        return content

print (re.sub('[A-Z]+', consider, sentence))

      

I didn't bother to use your words, however, once in my troubled mind. This is how it looks in use.

Please enter ADJECTIVEbig
Please enter NOUNbear
Please enter VERBgoes
Please enter NOUNhome
The big panda walked to the bear and then goes. A nearby home was unaffected by these events.

      



EDIT: Added in response to a comment.

import re

partsOfSpeech = ['NOUN', 'ADJECTIVE', 'ADVERB', 'VERB']
replacements = {_:'' for _ in partsOfSpeech}

for r in replacements:
    replacements[r] = input('Please enter ' + r.lower() + ': ')

madLibs = [
    'The ADJECTIVE panda walked to the NOUN and then VERB. A nearby NOUN was unaffected by these events.',
    'A NOUN ADVERB decided to VERB the NOUN'
    ]

def consider(matchobj):
    content = matchobj.group()
    if content in partsOfSpeech:
        return replacements[content]
    else:
        return content

for madLib in madLibs:
    print (re.sub('[A-Z]+', consider, madLib))

      

Result:

Please enter adjective: vast
Please enter adverb: smoothly
Please enter verb: went
Please enter noun: bear
The vast panda walked to the bear and then went. A nearby bear was unaffected by these events.
A bear smoothly decided to went the bear

      

+2


source


This is my code:

#! python3
# Mad Libs program to replace ADJECTIVE, NOUN, ADVERB, or VERB
import re,os
dir=os.getcwd()
readFile=open(dir)
contents=readFile.read()
readFile.close()
content=contents.split()

      

So, the above lines open the file, and contents

all the contents of the file are stored in . The content

individual words are stored independently.

i=0
for contents in content:
    if('ADJECTIVE' in contents):#Checks if the word is ADJECTIVE
        regex1=re.compile(r'ADJECTIVE')
        content[i]=regex1.sub(input('What is the ADJECTIVE?\nEnter:'),contents)
    elif ('NOUN' in contents):#Checks if the word is NOUN
        regex1=re.compile(r'NOUN')
        content[i]=regex1.sub(input('What is the NOUN?\nEnter:'),contents)
    elif ('VERB' in contents):#Checks if the word is VERB
        regex1=re.compile(r'VERB')
        content[i]=regex1.sub(input('What is the VERB?\nEnter:'),contents)
    elif ('ADVERB' in contents):#Checks if the word is adverb
        regex1=re.compile(r'ADVERB')
        content[i]=regex1.sub(input('What is the ADVERB?\nEnter:'),contents)
    i=i+1

      



Regular expression1 is responsible for replacing the individual inputs VERB, ADJECTIVE, NOUN, and ADVERB. content[i]

and i

to make sure the places and correct words are replaced.

contents=' '.join(content)
print(contents)
writeFile=open(dir,'w')
writeFile.write(contents)
writeFile.close()

      

Please feel free to correct me or solve this problem in a shorter way. Hope this solves your problem.

0


source







All Articles