2

I am trying to name a text file after the last directory in a file path. I need to be able to get this name for OS's that use either forward or backward slashes. I've successfully used the string split() method for forward slash file paths but not backslash. Also, when I try to print the backslash directory name the slashes are not included (probably reading as escape sequences); however, when I use re.search() method it still finds the slash.

How do I fix this?

See code below:

import re
import sys

targetDirectory = sys.argv[1]
filePathDirectorySeparator = ''
usesForwardSlashSeparator = re.search('/', targetDirectory)
if(usesForwardSlashSeparator):
    filePathDirectorySeparator = '/'
else:
    filePathDirectorySeparator = '\\'

fileName = targetDirectory.split(filePathDirectorySeparator)[-1]
file = open(fileName, 'w+')
file.write('HELLO')
file.close()

The link shows my console output (I'm not allowed to embed images yet apparently...)

Jerry Koolen
  • 31
  • 1
  • 4
  • I don't see the link so I've uploaded to imgur: http://imgur.com/a/ijLgK – Jerry Koolen Jul 30 '17 at 08:39
  • I'd guess that your shell is interpreting the backslashes, so that they never show up in `sys.argv` in Python. Can you try escaping them on the command line? – Blckknght Jul 30 '17 at 08:41
  • Have a look at [os.path](https://docs.python.org/3/library/os.path.html), and note that you can also use forward slashes in your Windows paths. – Thierry Lathuille Jul 30 '17 at 08:41
  • It doesn't look like this code actually uses `re.split`. – user2357112 Jul 30 '17 at 08:43
  • @user2357112 you're right, i'll update the post – Jerry Koolen Jul 30 '17 at 08:54
  • so, i should actually just be using os.path.basename(), as some of your hinted at. thanks for the help! still interested in how we can get string split() to work on backslashes if anyone can figure it out – Jerry Koolen Jul 30 '17 at 09:08
  • @JerryKoolen anomitr's solution would have suggested a better way, but the problem statement was 'python string split() on a backslash?' Marking an answer as accepted is to help for future references when someone else comes up with a similar problem! – Keerthana Prabhakaran Jul 30 '17 at 09:21

2 Answers2

2

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.

Keerthana Prabhakaran
  • 3,766
  • 1
  • 13
  • 23
2

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).

Anomitra
  • 1,111
  • 15
  • 31