I have code similar to:
chars = ['~', '*', '\\', ':', '<', '>', '|', '?', '"']
def ReplaceChars(value):
for c in chars:
value = value.replace(c, '')
return value
def RenamePath(root, path):
newFilePath = ReplaceChars(path)
os.rename(os.path.join(root, path), os.path.join(root, newFilePath))
def WalkFileSystem(dirroot):
# Main Walk Through File System
for root, dirs, files in os.walk(dirroot, topdown=False):
for name in dirs:
searchObj = re.search(r'[%s]' % ''.join(chars), name)
if searchObj:
RenamePath(root, name)
for name in files:
searchObj = re.search(r'[%s]' % ''.join(chars), name)
if searchObj:
RenamePath(root, name)
The issue is if a directory or file contains a backslash it won't remove it. By removing the r I no longer read it as a raw string and instead use four backslashes, two is needed by the regex pattern. The regex pattern appears in the first arg as I expect and the search picks it up. It just won't remove the backslash from the path string and I don't know why. Any ideas?
The raw string doesn't do anything useful in the r'[%s]' % ''.join(chars) interpolation, it first gets evaluated, doesn't escape anything, and then the chars is joined and substituted. So it's the same as doing '[%s]' % ''.join(chars).
The problem with \s here is that you need '\\\\' (or r'\\') for regex and '\\' for replacement. Regex needs one more level of escape, so you cannot use the same string for both:
>>> path = 'a\\path'
>>> re.search('[\\\\]', path)
<_sre.SRE_Match object at 0x10d5c6920>
>>> path = 'a\\path'
>>> path.replace('\\\\', '')
'a\\path'
>>> path.replace('\\', '')
'apath'
You can either use separate chars arrays for searching and replacing:
chars_search = ['~', '*', '\\\\', ':', '<', '>', '|', '?', '"']
chars_replace = ['~', '*', '\\', ':', '<', '>', '|', '?', '"']
or have it all in one:
chars = ['~', '*', '\\\\', '\\', ':', '<', '>', '|', '?', '"']
What suits you best.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With