Find and replace text iteratively from a list

Viewed 432

Suppose I have these text :

Donec sollicitudin ? malesuada. "Curabitur" arcu erat, accumsan
id imperdiet et, porttitor at sem. Quisque velit nisi, ? ut
lacinia in, ? id enim. Proin eget tortor risus.

and I have these texts in list :

["apple", "banana", "cherry"]

How can I replace each occurence of ? with each of the text in the list ? Expected output :

Donec sollicitudin apple malesuada. "Curabitur" arcu erat, accumsan
id imperdiet et, porttitor at sem. Quisque velit nisi, banana ut
lacinia in, cherry id enim. Proin eget tortor risus.

Is it possible to use notepad++ to achieve something like this for a longer text and list? Or is there any other technologies that I can use ?

4 Answers

You could try doing three regex replacements in succession:

Find:

([^?]*)?\?(.*)

Replace:

$1apple$2

The trick here is that ([^?]*)?\? matches everything up until the first question mark. This allows us to do a controlled replacement of only one ? placeholder at a time.

You would then repeat the above the above replacement from left to right for the other two keywords.

This Python script will get the job done. If there are more ? than replacements in the list, it will leave them as ?.

import re

replacements = ["apple", "banana", "cherry"]
lines = ""

with open("file.txt") as file:
    lines = file.read()

def replace(m):
    if not replacements:
        return "?"

    return replacements.pop(0)

lines = re.sub(r"\?", replace, lines)

with open("file.txt", "w") as file:
    file.write(lines)

Admittedly, there are better ways of doing this, such as not loading the entire file into a string.

You can use below regex:

\?(?!(.|\s)*\?(.|\s)*)

It will pick the last ? and provide you the index of it. After that you can replace it with the last element of your array (it would be better if you create a stack which contains ["apple", "banana", "cherry"] so that stack.pop method will always give you the last element.)

In Perl:

$text =~ s{\?}{shift @fruits}eg;  # Consumes @fruits array

Or

my $i = 0;
$text =~ s{\?}{$fruits[$i++]}g;   # Preserves @fruits

To cycle over @fruits (if the number of ?s exceeds the number of fruits):

my $i = 0;
$text =~ s{\?}{$fruits[ $i++ % @fruits ]}g;
Related