简体   繁体   中英

How to Find a String in a Text File And Replace Each Time With User Input in a Python Script?

I am new to python so excuse my ignorance.

Currently, I have a text file with some words marked as <>.

My goal is to essentially build a script which runs through a text file with such marked words. Each time the script finds such a word, it would ask the user for what it wants to replace it with.

For example, if I had a text file:

Today was a <<feeling>> day.

The script would run through the text file so the output would be:

Running script...
feeling? great
Script finished.

And generate a text file which would say:

Today was a great day.

Advice?

Edit: Thanks for the great advice. I have made a script that works for the most part like I wanted. Just one thing, Now I am working on if I have multiple variables with the same name (for instance. "I am <>. Bob is also <>,") the script would only prompt? feeling,. once and fill in all the variables with the same name.

Thanks so much for your help again.

import re
with open('in.txt') as infile:
    text = infile.read()
search = re.compile('<<([^>]*)>>')
text = search.sub(lambda m: raw_input(m.group(1) + '? '), text)
with open('out.txt', 'w') as outfile:
    outfile.write(text)

To open afile and loop through it:

Use raw_input to get input from user

Now, put this together and update you question if you run into problems:-)

I understand you want advice on how to structure your script, right? Here's what I would do:

  1. Read the file at once and close it (I personally don't like to have open file objects, especially if my filesystem is remote).
  2. Use a regular expression (phihag has suggested one in his answer , so I won't repeat it) to match the pattern of your placeholders. Find all of your placeholders and store them in a dictionary as keys.
  3. For each word in the dictionary, ask the user with raw_input (not just input ). And store them as values in the dictionary.
  4. When done, parse your text substituting any instance of a given placeholder (key) with the user word (value). This is also done with regex .

The reason for using a dictionary is that a given placeholder could occur more than once and you probably don't want to make the user repeat the entry over and over again...

Basically the same solution as that offerred by @phihag, but in script form

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import argparse
import re
from os import path

pattern = '<<([^>]*)>>'

def user_replace(match):
    return raw_input('%s? ' % match.group(1))


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('infile', type=argparse.FileType('r'))
    parser.add_argument('outfile', type=argparse.FileType('w'))
    args = parser.parse_args()

    matcher = re.compile(pattern)

    for line in args.infile:
        new_line = matcher.sub(user_replace, line)
        args.outfile.write(new_line)

    args.infile.close()
    args.outfile.close()

if __name__ == '__main__':
    main()

Usage: python script.py input.txt output.txt

Note that this script does not account for non-ascii file encoding.

Try something like this

lines = []
with open(myfile, "r") as infile:
    lines = infile.readlines()

outlines = []
for line in lines:
    index = line.find("<<")
    if index > 0:
        word = line[index+2:line.find(">>")]
        input = raw_input(word+"? ")
        outlines.append(line.replace("<<"+word+">>", input))
    else:
        outlines.append(line)

with open(outfile, "w") as output:
    for line in outlines:
        outfile.write(line)

Disclaimer: I haven't actually run this, so it might not work, but it looks about right and is similar to something I've done in the past.

How it works:

  • It parses the file in as a list where each element is one line of the file.
  • It builds the output list of lines. It iterates through the lines in the input, checking if the string << exist. If it does, it rips out the word inside the << and >> brackets, using it as the question for a raw_input query. It takes the input from that query and replaces the value inside the arrows (and the arrows) with the input. It then appends this value to the list. If it didn't see the arrows it simply appended the line.
  • After running through all the lines, it writes them to the output file. You can make this whatever file you want.

Some issues:

  1. As written, this will work for only one arrow statement per line. So if you had <<firstname>> <<lastname>> on the same line it would ignore the lastname portion. Fixing this wouldn't be too hard to implement - you could place a while loop using the index > 0 statement and holding the lines inside that if statement. Just remember to update the index again if you do that!
  2. It iterates through the list three times. You could likely reduce this to two, but if you have a small text file this shouldn't be a huge problem.
  3. It could be sensitive to encoding - I'm not entirely sure about that however. Worst case there you need to cast as a string.

Edit: Moved the +2 to fix the broken if statement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM