Search & Replace

Discussion in 'Python' started by DataSmash, Oct 26, 2006.

  1. DataSmash

    DataSmash Guest

    Hello,
    I need to search and replace 4 words in a text file.
    Below is my attempt at it, but this code appends
    a copy of the text file within itself 4 times.
    Can someone help me out.
    Thanks!

    # Search & Replace
    file = open("text.txt", "r")
    text = file.read()
    file.close()

    file = open("text.txt", "w")
    file.write(text.replace("Left_RefAddr", "FromLeft"))
    file.write(text.replace("Left_NonRefAddr", "ToLeft"))
    file.write(text.replace("Right_RefAddr", "FromRight"))
    file.write(text.replace("Right_NonRefAddr", "ToRight"))
    file.close()
    DataSmash, Oct 26, 2006
    #1
    1. Advertising

  2. In <>, DataSmash
    wrote:

    > I need to search and replace 4 words in a text file.
    > Below is my attempt at it, but this code appends
    > a copy of the text file within itself 4 times.


    Because you `write()` the whole text four times to the file. Make the 4
    replacements first and rebind `text` to the string with the replacements
    each time, and *then* write the result *once* to the file.

    > # Search & Replace
    > file = open("text.txt", "r")
    > text = file.read()
    > file.close()
    >
    > file = open("text.txt", "w")


    text = text.replace("Left_RefAddr", "FromLeft")
    text = text.replace("Left_NonRefAddr", "ToLeft")
    # ...
    file.write(text)
    file.close()

    Ciao,
    Marc 'BlackJack' Rintsch
    Marc 'BlackJack' Rintsch, Oct 26, 2006
    #2
    1. Advertising

  3. DataSmash

    Tim Chase Guest

    > Below is my attempt at it, but this code appends
    > a copy of the text file within itself 4 times.
    > Can someone help me out.

    [snip]
    > file = open("text.txt", "w")
    > file.write(text.replace("Left_RefAddr", "FromLeft"))
    > file.write(text.replace("Left_NonRefAddr", "ToLeft"))
    > file.write(text.replace("Right_RefAddr", "FromRight"))
    > file.write(text.replace("Right_NonRefAddr", "ToRight"))
    > file.close()



    Well, as you can see, you're writing (write()) the text 4 times.

    Looks like you want something like

    file.write(text.replace("Left_RefAddr",
    "FromLeft").replace("Left_NonRefAddr",
    "ToLeft").replace("Right_RefAddr",
    "FromRight").replace("Right_NonRefAddr", "ToRight"))


    which is about the equiv. of

    text = text.replace(...1...)
    text = text.replace(...2...)
    text = text.replace(...3...)
    text = text.replace(...4...)
    file.write(text)

    I would also be remiss if I didn't mention that it's generally
    considered bad form to use the variable-name "file", as it
    shadows the builtin "file".

    There are additional ways if replacements cause problems that
    then themselves get replaced, and this is an undesired behavior.
    However, it looks like your example doesn't have this problem,
    so the matter is moot.

    -tkc
    Tim Chase, Oct 26, 2006
    #3
  4. DataSmash a écrit :
    > Hello,
    > I need to search and replace 4 words in a text file.
    > Below is my attempt at it, but this code appends
    > a copy of the text file within itself 4 times.
    > Can someone help me out.
    > Thanks!
    >
    > # Search & Replace
    > file = open("text.txt", "r")

    NB : avoid using 'file' as an identifier - it shadows the builtin 'file'
    type.

    > text = file.read()
    > file.close()
    >
    > file = open("text.txt", "w")
    > file.write(text.replace("Left_RefAddr", "FromLeft"))
    > file.write(text.replace("Left_NonRefAddr", "ToLeft"))
    > file.write(text.replace("Right_RefAddr", "FromRight"))
    > file.write(text.replace("Right_NonRefAddr", "ToRight"))
    > file.close()
    >


    See Mark and Tim's answers for your bug. Another (potential) problem
    with your code is that it may not work too well for big files. It's ok
    if you know that the files content will always be small enough to not
    eat all memory. Else, taking a "line by line" approach is the canonical
    solution :

    def simplesed(src, dest, *replacements):
    for line in src:
    for target, repl in replacements:
    line = line.replace(target, repl)
    dest.write(line)

    replacements = [
    ("Left_RefAddr", "FromLeft"),
    ("Left_NonRefAddr", "ToLeft"),
    ("Right_RefAddr", "FromRight"),
    ("Right_NonRefAddr", "ToRight"),
    ]
    src = open("hugetext.txt", "r")
    dest = open("some-temp-name.txt", "w")
    simplesed(src, dest, *replacements)
    src.close()
    dest.close()
    os.rename("some-temp-name.txt", "hugetext.txt")

    HTH
    Bruno Desthuilliers, Oct 26, 2006
    #4
  5. DataSmash

    Paddy Guest

    DataSmash wrote:
    > Hello,
    > I need to search and replace 4 words in a text file.
    > Below is my attempt at it, but this code appends
    > a copy of the text file within itself 4 times.
    > Can someone help me out.
    > Thanks!
    >
    > # Search & Replace
    > file = open("text.txt", "r")
    > text = file.read()
    > file.close()
    >
    > file = open("text.txt", "w")
    > file.write(text.replace("Left_RefAddr", "FromLeft"))
    > file.write(text.replace("Left_NonRefAddr", "ToLeft"))
    > file.write(text.replace("Right_RefAddr", "FromRight"))
    > file.write(text.replace("Right_NonRefAddr", "ToRight"))
    > file.close()


    Check out the Pythons standard fileinput module. It also has options
    for in-place editing.

    (
    http://groups.google.com/group/comp.lang.python/msg/2d88c0f5e17f004e?hl=en&
    )

    - Pad.
    Paddy, Oct 27, 2006
    #5
  6. DataSmash wrote:
    > Hello,
    > I need to search and replace 4 words in a text file.
    > Below is my attempt at it, but this code appends
    > a copy of the text file within itself 4 times.
    > Can someone help me out.
    > Thanks!
    >
    > # Search & Replace
    > file = open("text.txt", "r")
    > text = file.read()
    > file.close()
    >
    > file = open("text.txt", "w")
    > file.write(text.replace("Left_RefAddr", "FromLeft"))
    > file.write(text.replace("Left_NonRefAddr", "ToLeft"))
    > file.write(text.replace("Right_RefAddr", "FromRight"))
    > file.write(text.replace("Right_NonRefAddr", "ToRight"))
    > file.close()
    >
    >


    Here's a perfect problem for a stream editor, like
    http://cheeseshop.python.org/pypi/SE/2.2 beta. This is how it works:

    >>> replacement_definitions = '''

    Left_RefAddr=FromLeft
    Left_NonRefAddr=ToLeft
    Right_RefAddr=FromRight
    Right_NonRefAddr=ToRight
    '''
    >>> import SE
    >>> Replacements = SE.SE (replacement_definitions)
    >>> Replacements ('text.txt', 'new_text.txt')


    That's all! Or in place:

    >>> ALLOW_IN_PLACE = 3
    >>> Replacements.set (file_handling_flag = ALLOW_IN_PLACE)
    >>> Replacements ('text.txt')


    This should solve your task.

    An SE object takes strings too, which is required for line-by-line
    processing and is very useful for development or verification:

    >>> print Replacements (replacement_definitions) # Use definitions as

    test data

    FromLeft=FromLeft
    ToLeft=ToLeft
    FromRight=FromRight
    ToRight=ToRight

    Checks out. All substitutions are made.


    Regards

    Frederic
    Frederic Rentsch, Oct 27, 2006
    #6
  7. DataSmash

    DataSmash Guest

    Really appreciate all the all the different answers and learning tips!
    DataSmash, Oct 27, 2006
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Brian Blais
    Replies:
    1
    Views:
    359
    Bruno Desthuilliers
    Jun 27, 2006
  2. Greg Ewing
    Replies:
    2
    Views:
    323
    Dieter Maurer
    Jun 29, 2006
  3. Alun
    Replies:
    3
    Views:
    4,462
    Masudur
    Feb 18, 2008
  4. Abby Lee
    Replies:
    5
    Views:
    366
    Abby Lee
    Aug 2, 2004
  5. Prasad S
    Replies:
    2
    Views:
    209
    Dr John Stockton
    Aug 27, 2004
Loading...

Share This Page