You have the right idea with escaping the backslashes, but despite how it looks, your input string doesn't actually have any backslashes in it. You need to escape them in the input, too!
>>> a = "1\\2\\3\\4" # Note the doubled backslashes here!
>>> print(a.split('\\')) # Split on '\\'
['1', '2', '3', '4']
You could also use a raw string literal for the input, if it's likely to have many backslashes. This notation is much cleaner to look at (IMO), but it does have some limitations: read the docs!
>>> a = r"1\2\3\4"
>>> print(a.split('\\'))
['1', '2', '3', '4']
If you're getting a elsewhere, and a.split('\\') doesn't appropriately split on the visible backslashes, that means you've got something else in there instead of real backslashes. Try print(repr(a)) to see what the "literal" string actually looks like.
>>> a = '1\2\3\4'
>>> print(a)
1☻♥♦
>>> print(repr(a))
'1\x02\x03\x04'
>>> b = '1\\2\\3\\4'
>>> print(b)
1\2\3\4
>>> print(repr(b))
'1\\2\\3\\4'
Answer from Henry Keiter on Stack OverflowYou have the right idea with escaping the backslashes, but despite how it looks, your input string doesn't actually have any backslashes in it. You need to escape them in the input, too!
>>> a = "1\\2\\3\\4" # Note the doubled backslashes here!
>>> print(a.split('\\')) # Split on '\\'
['1', '2', '3', '4']
You could also use a raw string literal for the input, if it's likely to have many backslashes. This notation is much cleaner to look at (IMO), but it does have some limitations: read the docs!
>>> a = r"1\2\3\4"
>>> print(a.split('\\'))
['1', '2', '3', '4']
If you're getting a elsewhere, and a.split('\\') doesn't appropriately split on the visible backslashes, that means you've got something else in there instead of real backslashes. Try print(repr(a)) to see what the "literal" string actually looks like.
>>> a = '1\2\3\4'
>>> print(a)
1☻♥♦
>>> print(repr(a))
'1\x02\x03\x04'
>>> b = '1\\2\\3\\4'
>>> print(b)
1\2\3\4
>>> print(repr(b))
'1\\2\\3\\4'
You can split a string by backslash using a.split('\\').
The reason this is not working in your case is that \x in your assignment a = "1\2\3\4" is interpreted as an octal number. If you prefix the string with r, you will get the intended result.
Assuming you have a correct path, then:
import os
# Note that we're using the **r** prefix to make it a raw string - backslashes don't escape
path = r'C:\Users\Desktop\TEST\Excel_Reports\1837.xlsx'
print os.path.split(path)[1]
# 1837.xlsx
You could also then further split to just get the base of the filename, eg:
print os.path.splitext(os.path.split(path)[1])[0]
# 1837
You need to make the literal for te a raw string
>>> te = r'C:\Users\Desktop\TEST\Excel_Reports\1837.xlsx'
>>> import os
>>> te.split("\\") # can't use os.path.sep as my repl is on linux
['C:', 'Users', 'Desktop', 'TEST', 'Excel_Reports', '1837.xlsx']
This is due to the syntax for python literal strings. \g, \n, \t etc would also cause problems. The other slashes don't need to be escaped since the character following isn't a valid escape sequence - but it's confusing as hell. Better to use the raw string syntax
If you're getting te from some place other than a source file eg an ini file or a database (as you should), you wouldn't even see this problem.
I think you're trying harder than you need to. Python has an os module which has a function to do exactly what you want, independent of platform. Here, you just need to use
fileName=os.path.basename(targetDirectory)
Also, if you're using Python you should seriously consider moving away from camel case (fileName) to the more Pythonic snake case (file_name).
A small example,
>>> print s
this/hello\
>>> import re
>>> re.split('/',s)
['this', 'hello\\']
>>> re.split('\\',s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 171, in split
return _compile(pattern, flags).split(string, maxsplit)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 251, in _compile
raise error, v # invalid expression
sre_constants.error: bogus escape (end of line)
>>> re.split(r'\\',s)
['this/hello', '']
'r' prefix matters!
Reference!
That is,
When an "r" or "R" prefix is present, a character following a backslash is included in the string without change, and all backslashes are left in the string. For example, the string literal r"\n" consists of two characters: a backslash and a lowercase "n". String quotes can be escaped with a backslash, but the backslash remains in the string; for example, r"\"" is a valid string literal consisting of two characters: a backslash and a double quote; r"\" is not a valid string literal (even a raw string cannot end in an odd number of backslashes). Specifically, a raw string cannot end in a single backslash (since the backslash would escape the following quote character). Note also that a single backslash followed by a newline is interpreted as those two characters as part of the string, not as a line continuation.
Your first backslash is escaping the second at the level of the string literal. But the regex engine needs that backslash escaped also, since it's a special character for regex too.
Use a "raw" string literal (e.g. r' |/|\\') or quadruple backslash.
try
import re
def get_asset_str(in_str):
split = re.split(r' |/|\\' , in_str)
To capture a delimiter, it's easier to use findall instead of split:
re.findall(r'[^\\/]+|[\\/]', string)
[^\\/]+ would find 1 or more occurrences of sub-strings that do not contain forward or backward slash. | works as an or operator. Finally, [\\/] will match with the occurrences of forward and backward slash. The result would provide separate sub-strings for the occurrences of forward and backward slash and string matches where they do not occur.
As for why your code didn't work, your expression is (\\/). When Python interpreter parses this, it sees an escaped slash and creates a string of four characters: ( \ / ). Then, this string is sent to the regex engine, which also does escaping. It sees a slash followed by a backslash, and since backslash is not special, it "escapes" to itself, so the final expression is just (/). Finally, re applies this expression, splits by a backslash and captures it - exactly what you're observing.
The correct command for your approach would be re.split('([\\\/])',string) due to double escaping.
The moral of the story: always use raw literals r"..." with regexes to avoid double escaping issues.
I think, this solution gives exactly what you want:
import re
testStr = '-------/--------\\---------/------\\'
parts = re.split('(\\\\|/)', testStr)
for p in parts:
print('p=' + p)
Result:
p=-------
p=/
p=--------
p=\
p=---------
p=/
p=------
p=\
p=