search and replace first amount of strings instances with one thing and a second amount of instances with another thing-

Peter Otten __peter__ at web.de
Sat Sep 23 03:56:58 EDT 2017


Peter Otten wrote:

> validationmail1 at gmail.com wrote:
> 
>> i have a code in python to search and replace what i need though is to
>> replace the first say 10 instances of the number 1 with 2 and the second
>> 10 instances with the number 3. anybody knows how to do that?
>> 
>> fin = open(r'F:\1\xxx.txt')
>> fout = open(r'F:\1\xxx2.txt', "wt")
>> for line in fin:
>>     fout.write( line.replace('1', '2') )
>> fin.close()
>> fout.close()
> 
> If the search token can occur more than once in a line you cannot use
> str.replace(). Here's a solution without regular expressions. I
> implemented the "repeat something" and the "replace token with something
> different every time" separately.
> 
> $ cat replace_increasing.py
> #!/usr/bin/env python3

Should also work with python2 once you add

try:
    from future_builtins import zip, map
except ImportError:
    pass

to make map() lazy.

> from itertools import chain, count, repeat

Lest you die of an itertools overdose here's a slightly simpler version:

#!/usr/bin/env python3


def numberstrings(repeat, start=1):
    """
    >>> [v for i, v in zip(range(10), numberstrings(3, 1))]
    ['1', '1', '1', '2', '2', '2', '3', '3', '3', '4']
    """
    value = start
    while True:
        for _i in range(repeat):
            yield str(value)
        value += 1


def make_replace(token, replace):
    """
    >>> r = make_replace("x", "ABCDEFGH")
    >>> r("onextwoxthreex")
    'oneAtwoBthreeC'
    >>> r("no match")
    'no match'
    >>> r("x at start")
    'D at start'
    >>> r("somexsomewhere")
    'someEsomewhere'
    >>> r("xxx")
    'FGH'
    >>> try: r("x")
    ... except StopIteration: "OK"
    'OK'
    """
    replaceiter = iter(replace)

    def replace(line):
        parts = line.split(token)
        return "".join(
            [p + next(replaceiter) for p in parts[:-1]]
            + parts[-1:]
        )
    return replace


def main():
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("infile")
    parser.add_argument("outfile")
    parser.add_argument("token")
    parser.add_argument("-r", "--repeat", type=int, default=10)
    args = parser.parse_args()

    replace = make_replace(args.token, numberstrings(args.repeat))
    with open(args.infile) as instream:
        with open(args.outfile, "w") as outstream:
            outstream.writelines(replace(line) for line in instream)


if __name__ == "__main__":
    main()





More information about the Python-list mailing list