I would like to replace the backslash \ in a windows path with forward slash / using python.
Unfortunately I'm trying from hours but I cannot solve this issue.. I saw other questions here but still I cannot find a solution
Can someone help me?
This is what I'm trying:
path = "\\ftac\admin\rec\pir"
path = path.replace("\", "/")
But I got an error (SyntaxError: EOL while scanning string literal) and is not return the path as I want:
//ftac/admin/rec/pir, how can I solve it?
I also tried path = path.replace(os.sep, "/") or path = path.replace("\\", "/") but with both methods the first double backslash becomes single and the \a was deleted..
Oh boy, this is a bit more complicated than first appears.
Your problem is that you have stored your windows paths as normal strings, instead of raw strings. The conversion from strings to their raw representation is lossy and ugly.
This is because when you make a string like "\a", the intperter sees a special character "\x07".
This means you have to manually know which of these special characters you expect, then [lossily] hack back if you see their representation (such as in this example):
def str_to_raw(s):
raw_map = {8:r'\b', 7:r'\a', 12:r'\f', 10:r'\n', 13:r'\r', 9:r'\t', 11:r'\v'}
return r''.join(i if ord(i) > 32 else raw_map.get(ord(i), i) for i in s)
>>> str_to_raw("\\ftac\admin\rec\pir")
'\\ftac\\admin\\rec\\pir'
Now you can use the pathlib module, this can handle paths in a system agnsotic way. In your case, you know you have Windows like paths as input, so you can use as follows:
import pathlib
def fix_path(path):
# get proper raw representaiton
path_fixed = str_to_raw(path)
# read in as windows path, convert to posix string
return pathlib.PureWindowsPath(path_fixed).as_posix()
>>> fix_path("\\ftac\admin\rec\pir")
'/ftac/admin/rec/pir'
Related
I am trying to create a directory in my Python code but I can't use backslash \ in a string. Every time I do it gives me an unexpected token error.
I would like my code to look something like this:
dir = os.getcwd() + "\FolderIWantToCreate"
If I use / (forward slash), it gives me an error because my directory paths use backslash. However if I type \ (backslash) anywhere in my code, even inside "", it doesn't register the backslash as a string, it says unexpected token.
How can I overcome this?
\ is the escape character in python. If you want to use \ in a string you have to escape it, i.e.:
"\\"
For more, see: https://docs.python.org/2.0/ref/strings.html
You have two options:
You can either escape the escape character \ by adding an extra \ before it, like this: "\\FolderIWantToCreate",
You can use the r prefix before the string to tell python that the string that follows is a raw string, like this: r"\FolderIWantToCreate"
If you are dealing with paths and look e.g. for OS intercompatibility, consider using the pathlib package. More info on how to use it when e.g. creating new folders, see here.
If you really have to use that notation anyways, then an option would be to make it a "raw" string:
s = r'\FolderIWantToCreate'
more on that e.g. here.
Please use the Escape sequence when ever you are using special characters
dir = os.getcwd() + "\\FolderIWantToCreate"
Reference : 2.4.1 String literals
dir = os.getcwd() + "\\FolderIWantToCreate"
Just adding another answer which I think you should know;
Assuming you are on Windows
You can use os.path.join() with os.sep to overcome the issue you are facing.
I do not have a Windows VM with me to give you a concrete example.
I have a path in a variable like that:
path = "C:\HT_Projeler\7\Kaynak\wrapped_gedizw.tif"
Which is incorrect because it contains escape sequences:
>>> path
'C:\\HT_Projeler\x07\\Kaynak\\wrapped_gedizw.tif'
How can I fix the path in this variable so it becomes equivalent to r"C:\HT_Projeler\7\Kaynak\wrapped_gedizw.tif" or "C:/HT_Projeler/7/Kaynak/wrapped_gedizw.tif"?
I know the topic is common and I investigated many questions (1,2 etc.) in here.
ADD
Here is my exact script:
...
basinFile = self._gv.basinFile
basinDs = gdal.Open(basinFile, gdal.GA_ReadOnly)
basinNumberRows = basinDs.RasterYSize
basinNumberCols = basinDs.RasterXSize
...
In here self._gv.basinFile consists my path. So I cannot put "r" beginngin of self._gv.basinFile
If you insert paths in Python code, just use raw strings, as other have suggested.
If instead that string is out of your control, there's not much you can do "after the fact". Escape sequences conversion is not injective, so, given a string where escape sequences have already been processed, you cannot "go back" univocally. IOW, if someone incorrectly writes:
path = "C:\HT_Projeler\7\Kaynak\wrapped_gedizw.tif"
as you show, you get
'C:\\HT_Projeler\x07\\Kaynak\\wrapped_gedizw.tif'
and there's no way to guess surely "what they meant", because that \x07 may have been written as \7, or \x07, or \a. Heck, any letter may have been originally written as an escape sequence - what you see in that string as an a may have actually been \x61.
Long story short: your caller is responsible for giving you correct data. Once it's corrupted there's no way to come back.
In the general case, there is no way to tell whether a character in a path is correct or not without externally checking the actual paths on your computer (and "special character" is not really well-defined; how do you know that the path wasn't \0x41 which got converted to A anyway?)
As a weak heuristic, you could look for path names within a particular editing distance, for example.
import os
from difflib import SequenceMatcher as similarity # or whatever
path_components = os.path.split(variable)
path = ''
for p in path_components:
npath = os.path.join(path, p)
if not os.path.exists(npath):
similar = reversed(sorted([(similarity(None, x, p).ratio(), x) in os.listdir(npath)]))
# recurse on most similar, second most similar, etc? or something
path = npath
I'm trying to escape the backslash, but trying to understand the right way of doing it
foo = r'C:\Users\test.doc'
The above works fine
However, when I want to escape the path stored in a variable
For example :
parser.add_argument('-s', '--source', type = str, help = 'Source file path')
Now, how do escape the value in - args.source
So there are a few escape sequences to be aware of in python and they are mainly these.
So when the string for that file location is parsed by the add_argument method it may not be interpreted as a raw string like you've declared and there will be no way to escape the backslashes outside of the declaration.
What you can do instead is to keep it as a regular string (removing the 'r' prefix from the string) and using the escape character for a backslash in any places there may be conflict with another escape character (in this case \t). This may work as the method may evaluate the string correctly.
Try declaring your string like this.
foo = "C:\Users\\test.doc"
Hopefully this helps fix your issue!
EDIT:
In response to handling the dynamic file location you could maybe do something like the following!
def clean(s):
s = s.replace("\t", "\\t")
s = s.replace("\n", "\\n")
return s
Until you've covered all of your bases with what locations you may need to work with! This solution might be more appropriate for your needs. It's kind of funny I didn't think of doing it this way before. Hopefully this helps!
I'm trying to find a way to print a string in raw form from a variable. For instance, if I add an environment variable to Windows for a path, which might look like 'C:\\Windows\Users\alexb\', I know I can do:
print(r'C:\\Windows\Users\alexb\')
But I cant put an r in front of a variable.... for instance:
test = 'C:\\Windows\Users\alexb\'
print(rtest)
Clearly would just try to print rtest.
I also know there's
test = 'C:\\Windows\Users\alexb\'
print(repr(test))
But this returns 'C:\\Windows\\Users\x07lexb'
as does
test = 'C:\\Windows\Users\alexb\'
print(test.encode('string-escape'))
So I'm wondering if there's any elegant way to make a variable holding that path print RAW, still using test? It would be nice if it was just
print(raw(test))
But its not
I had a similar problem and stumbled upon this question, and know thanks to Nick Olson-Harris' answer that the solution lies with changing the string.
Two ways of solving it:
Get the path you want using native python functions, e.g.:
test = os.getcwd() # In case the path in question is your current directory
print(repr(test))
This makes it platform independent and it now works with .encode. If this is an option for you, it's the more elegant solution.
If your string is not a path, define it in a way compatible with python strings, in this case by escaping your backslashes:
test = 'C:\\Windows\\Users\\alexb\\'
print(repr(test))
In general, to make a raw string out of a string variable, I use this:
string = "C:\\Windows\Users\alexb"
raw_string = r"{}".format(string)
output:
'C:\\\\Windows\\Users\\alexb'
You can't turn an existing string "raw". The r prefix on literals is understood by the parser; it tells it to ignore escape sequences in the string. However, once a string literal has been parsed, there's no difference between a raw string and a "regular" one. If you have a string that contains a newline, for instance, there's no way to tell at runtime whether that newline came from the escape sequence \n, from a literal newline in a triple-quoted string (perhaps even a raw one!), from calling chr(10), by reading it from a file, or whatever else you might be able to come up with. The actual string object constructed from any of those methods looks the same.
I know i'm too late for the answer but for people reading this I found a much easier way for doing it
myVariable = 'This string is supposed to be raw \'
print(r'%s' %myVariable)
try this. Based on what type of output you want. sometime you may not need single quote around printed string.
test = "qweqwe\n1212as\t121\\2asas"
print(repr(test)) # output: 'qweqwe\n1212as\t121\\2asas'
print( repr(test).strip("'")) # output: qweqwe\n1212as\t121\\2asas
Get rid of the escape characters before storing or manipulating the raw string:
You could change any backslashes of the path '\' to forward slashes '/' before storing them in a variable. The forward slashes don't need to be escaped:
>>> mypath = os.getcwd().replace('\\','/')
>>> os.path.exists(mypath)
True
>>>
Just simply use r'string'. Hope this will help you as I see you haven't got your expected answer yet:
test = 'C:\\Windows\Users\alexb\'
rawtest = r'%s' %test
I have my variable assigned to big complex pattern string for using with re module and it is concatenated with few other strings and in the end I want to print it then copy and check on regex101.com.
But when I print it in the interactive mode I get double slash - '\\w'
as #Jimmynoarms said:
The Solution for python 3x:
print(r'%s' % your_variable_pattern_str)
Your particular string won't work as typed because of the escape characters at the end \", won't allow it to close on the quotation.
Maybe I'm just wrong on that one because I'm still very new to python so if so please correct me but, changing it slightly to adjust for that, the repr() function will do the job of reproducing any string stored in a variable as a raw string.
You can do it two ways:
>>>print("C:\\Windows\Users\alexb\\")
C:\Windows\Users\alexb\
>>>print(r"C:\\Windows\Users\alexb\\")
C:\\Windows\Users\alexb\\
Store it in a variable:
test = "C:\\Windows\Users\alexb\\"
Use repr():
>>>print(repr(test))
'C:\\Windows\Users\alexb\\'
or string replacement with %r
print("%r" %test)
'C:\\Windows\Users\alexb\\'
The string will be reproduced with single quotes though so you would need to strip those off afterwards.
To turn a variable to raw str, just use
rf"{var}"
r is raw and f is f-str; put them together and boom it works.
Replace back-slash with forward-slash using one of the below:
re.sub(r"\", "/", x)
re.sub(r"\", "/", x)
This does the trick
>>> repr(string)[1:-1]
Here is the proof
>>> repr("\n")[1:-1] == r"\n"
True
And it can be easily extrapolated into a function if need be
>>> raw = lambda string: repr(string)[1:-1]
>>> raw("\n")
'\\n'
i wrote a small function.. but works for me
def conv(strng):
k=strng
k=k.replace('\a','\\a')
k=k.replace('\b','\\b')
k=k.replace('\f','\\f')
k=k.replace('\n','\\n')
k=k.replace('\r','\\r')
k=k.replace('\t','\\t')
k=k.replace('\v','\\v')
return k
Here is a straightforward solution.
address = 'C:\Windows\Users\local'
directory ="r'"+ address +"'"
print(directory)
"r'C:\\Windows\\Users\\local'"
I have been making an mp3 player with Tkinter and the module mp3play.
Say i had the song to play: C:\Music\song.mp3
and to play that song i have to run this script:
import mp3play
music_file=r'C:\Music\song.mp3'
clip = mp3play.load(music_file)
clip.play()
Easy enough, my problem though is getting the "r" there.
i have tried:
import mp3play
import re
music_file="'C:\Music\song.mp3'"
music_file='r'+music_file
music_file=re.sub('"','',music_file)
print music_file
clip = mp3play.load(music_file)
clip.play()
Which gets the output: r'C:\Music\song.mp3'
but it is a string, so it wont read the file.
The 'r' in the front denotes a particular category of string called raw string. You can't get that by adding two strings or re substituting a string. It is just a string type, but with the escape characters take care.
>>> s = r'something'
>>> s
'something'
>>>
When you are writing the script, use the 'r', if you are getting the input via raw_input, python will take care of escaping the characters. So, the question is why are you trying to do that?
try:
music_file='C:/Music/song.mp3'
In Python, the r prefix introduces a raw string. Outside of raw strings, backslash (\) characters are considered as escape characters and have to be escaped themselves (by doubling them).
Try a simple string instead:
music_file = 'C:\\Music\\song.mp3'
The r you are talking about has to be placed before a string definition, and tells python that the following string is "raw", meaning it will ignore backslash escapes (so it doesn't error on invalid backslashes in filenames, for example).
Why don't you just do it like in the first example? I don't see what you are trying to accomplish in the second example.
you can try music_file = r'%s' % path_to_file
As a few of the other answers have pointed out (I'm just posting this as an answer because it seemed kind of silly to make it a comment), what you've given in your first code block is exactly what the contents of your script should be. You don't need to do anything special to get the r there. In fact the 'r' is not part of the string, it's part of the code that makes the string.