-1

I wrote a Python script that iterates over all files in a specific directory. It opens files in read-only mode, finds specific strings from an XML file, and replaces them accordingly.

The problem is, if, for example, I want to change "icon.png" to "bear.png", the script will also work on "professional_icon.png" and will replace it with "professional_bear.png" - it is not what I want to achieve.

import sys
import re
import os
import shutil
import xml.etree.cElementTree as ET


drc = '/home/user/Desktop/Convert_here'
backup = '/home/user/Desktop/Rename_icons/tmp_backup'
tree = ET.parse('list.xml')
root = tree.getroot()
records = []

for child in root:
    find = child.find('FINDEXACT').text
    replace = child.find('REPLACEEXACT').text
    records.append((find, replace))
            
    pattern = re.compile(find)
        
    for dirpath, dirname, filename in os.walk(drc):
        for fname in filename:
            path = os.path.join(dirpath, fname) 
            strg = open(path).read() 
            if re.search(pattern, strg):
                print path, strg
                shutil.copy2(path, backup) 
                strg = strg.replace(find, replace) 
                f = open(path, 'w') 
                f.write(strg) 
                f.close() 

list.xml:

<SEARCH>
<SEARCHFOR>
    <FINDEXACT>icon.png</FINDEXACT>
    <REPLACEEXACT>bear.png</REPLACEEXACT>
</SEARCHFOR>
<SEARCHFOR>
    <FINDEXACT>professional_icon.png</FINDEXACT>
    <REPLACEEXACT>wolf.png</REPLACEEXACT>
</SEARCHFOR>
</SEARCH>

I tried to change pattern = re.compile(find) to pattern = re.match(find, replace) but it does not seem to work at all. Is there a way to change this script so it only works for exact matches?

Any help would be appreciated.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Can you check and compare the length of the search string and the filename? – hasleron Oct 28 '20 at 12:38
  • This script only works by opening specific files, for example, .txt; .ui; .cpp; .h; .py etc I am writing it to use it for rewriting old user interface (Qt .ui). There is tons of icon names to change and tons of .ui forms.. – benzodiazepinegaba Oct 28 '20 at 12:47
  • Do you have to use `re`? Would it not be simpler to just check the file name against the desired name using `==`? – gmdev Oct 28 '20 at 13:19

1 Answers1

1

It appears that you only want to do the substitution when the match is immediately preceded by a non-word character or start of the string. So:

Use as your regular expression:

find = r'\b' + child.find('FINDEXACT').text

And then you should use a regular expression substitution:

strg = pattern.sub(replace, strg)

You should also close your input files.

Booboo
  • 38,656
  • 3
  • 37
  • 60