Python에서 도스 경로를 구성요소로 분할하는 방법
도스 경로를 나타내는 문자열 변수가 있음:
var = "d:\stuff\morestuff\furtherdown\THEFILE.txt"
이 문자열을 다음과 같이 나누고 싶다.
[ "d", "stuff", "morestuff", "furtherdown", "THEFILE.txt" ]
나는 사용해 본 적이 있다.split()
, 그리고replace()
첫 번째 백슬래시만 처리하거나 문자열에 16진수만 삽입한다.
이 문자열 변수를 어떻게든 원시 문자열로 변환해야 구문 분석할 수 있어.
이것을 하는 가장 좋은 방법은 무엇인가?
의 내용 또한 덧붙여야겠습니다.var
즉, 구문 분석하려는 경로는 실제로 명령줄 쿼리의 반환 값입니다.내가 직접 생성하는 경로 데이터가 아니야.파일에 저장되어 있으며 명령줄 도구가 백슬래시를 벗어나지 않는다.
하고 싶다.
import os
path = os.path.normpath(path)
path.split(os.sep)
먼저 경로 문자열을 OS에 적합한 문자열로 표준화하십시오.그러면os.sep
문자열 함수 분할에서 구분 기호로 사용하기에 안전해야 한다.
나는 사람들이 자기 길을 만지작거리다가 잘못 알아가는 바람에 여러 번 물렸다.공간, 슬래시, 백슬래시, 콜론 -- 혼란의 가능성은 끝이 없지만, 어쨌든 실수는 쉽게 일어난다.그래서 나는 용법을 고수한다.os.path
, 그리고 그것을 근거로 추천한다.
(그러나 덕으로 가는 길은 가장 쉽게 가는 길이 아니며, 이것을 발견했을 때 많은 사람들은 바로 지옥으로 가는 미끄러운 길을 택하고 싶은 유혹을 받는다.그들은 언젠가는 모든 것이 산산조각이 날 때까지 깨닫지 못할 것이고, 그들은, 아니, 더 가능성이 높은 누군가는 왜 모든 것이 잘못되었는지 알아내야 하며, 누군가 슬래시와 백슬래시를 섞는 파일 이름을 만들었음이 밝혀지고, 어떤 사람들은 그 답이 "그러지 말라"고 제안한다.이 사람들처럼 굴지 마슬래시와 백슬래시를 섞은 사람을 제외하고 - 원한다면 그 사람이 될 수 있다.)
다음과 같은 드라이브와 경로+ 파일을 얻을 수 있다.
drive, path_and_file = os.path.splitdrive(path)
경로 및 파일 가져오기:
path, file = os.path.split(path_and_file)
개별 폴더 이름을 얻는 것은 특별히 편리한 것은 아니지만, 나중에 실제로 잘 작동하는 것을 찾는 즐거움을 높이는 일종의 솔직한 중간 불편함이다.
folders = []
while 1:
path, folder = os.path.split(path)
if folder != "":
folders.append(folder)
elif path != "":
folders.append(path)
break
folders.reverse()
(이거 터진다."\"
을 시작할 때folders
만약 그 길이 원래 절대적이었다면.그걸 원하지 않으면 코드를 조금 잃을 수도 있다.)
파이톤 >=3.4에서 이것은 훨씬 더 간단해졌다.이제 당신은 어떤 경로의 모든 부분을 얻는데 사용할 수 있다.
예:
>>> from pathlib import Path
>>> Path('C:/path/to/file.txt').parts
('C:\\', 'path', 'to', 'file.txt')
>>> Path(r'C:\path\to\file.txt').parts
('C:\\', 'path', 'to', 'file.txt')
Python 3의 Windows 설치에서는 사용자가 Windows 경로로 작업하고 있다고 가정하고 *nix에서는 posix 경로로 작업한다고 가정한다.이것은 보통 당신이 원하는 것이지만 만약 그렇지 않다면 당신은 수업을 이용할 수 있다.pathlib.PurePosixPath
또는pathlib.PureWindowsPath
필요한 경우:
>>> from pathlib import PurePosixPath, PureWindowsPath
>>> PurePosixPath('/path/to/file.txt').parts
('/', 'path', 'to', 'file.txt')
>>> PureWindowsPath(r'C:\path\to\file.txt').parts
('C:\\', 'path', 'to', 'file.txt')
>>> PureWindowsPath(r'\\host\share\path\to\file.txt').parts
('\\\\host\\share\\', 'path', 'to', 'file.txt')
편집: pathlib2에 대한 백포트를 사용할 수도 있음: pathlibathlib2
당신은 간단히 가장 많은 피토닉 접근법을 사용할 수 있다.
import os
your_path = r"d:\stuff\morestuff\furtherdown\THEFILE.txt"
path_list = your_path.split(os.sep)
print path_list
다음과 같은 이점을 누리십시오.
['d:', 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt']
여기서 단서는 사용이다.os.sep
대신에'\\'
또는'/'
, 이것이 시스템을 독립적으로 만들기 때문에.
드라이브 문자에서 콜론을 제거하려면(드라이브 문자에서 콜론을 제거하려는 이유를 알 수 없지만) 다음을 입력하십시오.
path_list[0] = path_list[0][0]
좀 더 간결한 솔루션을 위해 다음을 고려하십시오.
def split_path(p):
a,b = os.path.split(p)
return (split_path(a) if len(a) and len(b) else []) + [b]
여기서 문제는 애초에 어떻게 문자열을 만드느냐에서 시작된다.
a = "d:\stuff\morestuff\furtherdown\THEFILE.txt"
Python은 이 방법을 통해 다음과 같은 사례를 특별하게 다루려고 한다.\s
\m
\f
, 그리고\T
.당신의 경우\f
다른 백슬래시가 올바르게 처리되는 동안 폼피드(0x0C)로 처리된다.다음 중 하나를 수행해야 한다.
b = "d:\\stuff\\morestuff\\furtherdown\\THEFILE.txt" # doubled backslashes
c = r"d:\stuff\morestuff\furtherdown\THEFILE.txt" # raw string, no doubling necessary
그러면 이것들 중 하나를 나누면 원하는 결과를 얻을 수 있을 거야.
나는 실제로 이 문제에 진정한 답을 줄 수는 없지만(내가 직접 하나를 찾기를 희망하며 여기 왔기 때문에), 내게는 접근방식의 차이와 언급된 모든 주의사항은 파이썬의 os.path 모듈이 내장 기능으로 이것을 절실히 필요로 한다는 가장 확실한 지표다.
발전기를 이용한 기능적 방법.
def split(path):
(drive, head) = os.path.splitdrive(path)
while (head != os.sep):
(head, tail) = os.path.split(head)
yield tail
작동 중:
>>> print([x for x in split(os.path.normpath('/path/to/filename'))])
['filename', 'to', 'path']
관한 것.mypath.split("\\")
라고 표현하는 것이 좋을 것이다.mypath.split(os.sep)
.sep
특정의 로子:\
윈도우의 경우를 /
유닉스 등), 그리고 파이톤 빌드는 어떤 것을 사용해야 할지 알고 있다.사용한다면sep
그러면 당신의 코드는 플랫폼 불가지론자가 될 것이다.
재귀적으로 할 수 있다.os.path.split
현악기
import os
def parts(path):
p,f = os.path.split(path)
return parts(p) + [f] if f else [p]
일부 경로 문자열에 대해 테스트하고 경로 재조립os.path.join
>>> for path in [
... r'd:\stuff\morestuff\furtherdown\THEFILE.txt',
... '/path/to/file.txt',
... 'relative/path/to/file.txt',
... r'C:\path\to\file.txt',
... r'\\host\share\path\to\file.txt',
... ]:
... print parts(path), os.path.join(*parts(path))
...
['d:\\', 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt'] d:\stuff\morestuff\furtherdown\THEFILE.txt
['/', 'path', 'to', 'file.txt'] /path\to\file.txt
['', 'relative', 'path', 'to', 'file.txt'] relative\path\to\file.txt
['C:\\', 'path', 'to', 'file.txt'] C:\path\to\file.txt
['\\\\', 'host', 'share', 'path', 'to', 'file.txt'] \\host\share\path\to\file.txt
목록의 첫 번째 요소는 드라이브 문자, UNC 경로 및 절대 및 상대 경로에 따라 다르게 처리해야 할 수 있다.마지막 변경[p]
로[os.path.splitdrive(p)]
드라이브 문자와 디렉터리 루트를 튜플로 분리하여 문제를 해결하십시오.
import os
def parts(path):
p,f = os.path.split(path)
return parts(p) + [f] if f else [os.path.splitdrive(p)]
[('d:', '\\'), 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt']
[('', '/'), 'path', 'to', 'file.txt']
[('', ''), 'relative', 'path', 'to', 'file.txt']
[('C:', '\\'), 'path', 'to', 'file.txt']
[('', '\\\\'), 'host', 'share', 'path', 'to', 'file.txt']
편집: 나는 이 답변이 사용자 1556435에 의해 위에 제시된 답변과 매우 유사하다는 것을 깨달았다.경로의 드라이브 컴포넌트 처리가 달라서 답변을 남긴다.
나한테는 효과가 있어:
>>> a=r"d:\stuff\morestuff\furtherdown\THEFILE.txt"
>>> a.split("\\")
['d:', 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt']
물론 첫 번째 구성 요소에서 결장을 제거해야 할 수도 있지만, 유지하면 경로를 다시 조립할 수 있다.
그r
수정자는 문자열을 "원시"로 표시하며 내장된 백슬래시가 어떻게 두 배로 증가하지 않는지 주의하십시오.
os.path.basename 함수를 사용하므로 반환된 목록에 슬래시를 추가하지 않으므로 다음을 사용한다.또한 어떤 플랫폼의 슬래시(즉, 윈도우의 슬래시)와도 작동한다. \\\\
또는 유닉스의 /
. 그리고 더 나아가서, 그것은 더하지 않는다.\\\\\\\\
서버 경로에 사용하는 창 :)
def SplitPath( split_path ):
pathSplit_lst = []
while os.path.basename(split_path):
pathSplit_lst.append( os.path.basename(split_path) )
split_path = os.path.dirname(split_path)
pathSplit_lst.reverse()
return pathSplit_lst
다음의 경우:
\\\\\\\server\\\\folder1\\\\folder2\\\\folder3\\\\folder4
다음과 같은 혜택을 누리십시오.
['server','folder1','folder2','folder3','folder4']
매우 쉽고 간단한 방법:
var.replace('\\', '/').split('/')
다른 사람들이 설명한 대로 - 당신의 문제는\
문자열 리터럴/리터럴의 이스케이프 문자.OTOH, 만약 당신이 다른 소스에서 파일 경로 문자열을 가지고 있었다면(파일로부터 읽거나, 콘솔에서 읽거나, os 함수에 의해 반환됨) - '\\'나 r'\'로 분할하는 데 문제가 없었을 것이다.
그리고 다른 사람들이 제안한 것처럼, 만약 당신이 사용하길 원한다면\
프로그램 리터럴에서는 복제해야 한다.\\
아니면 문자 전체를 앞에 붙여야 한다.r
, 그렇게.r'lite\ral'
또는r"lite\ral"
파서가 그걸 변환하는 걸 피하려면\
, 그리고r
CR(캐리지 리턴) 문자에 연결.
하지만 한 가지 더 방법이 있다 - 백슬래시를 사용하지 마라.\
코드의 경로 이름!지난 세기 이래로 Windows는 슬래시를 디렉토리 구분자로 사용하는 경로 이름을 인식하고 잘 작동한다./
어떻게 된 일인지 아는 사람이 많지 않아그러나 다음과 같이 작동한다.
>>> var = "d:/stuff/morestuff/furtherdown/THEFILE.txt"
>>> var.split('/')
['d:', 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt']
그런데 이렇게 하면 당신의 코드가 Unix, Windows, Mac에서 작동하게 될 것이다...왜냐하면 모두 다 사용하기 때문이다./
디렉토리 구분자로...모듈의 미리 정의된 상수를 사용하지 않으려는 경우에도os
.
파일이 있다고 가정해 보십시오.filedata.txt
내용 포함:
d:\stuff\morestuff\furtherdown\THEFILE.txt
d:\otherstuff\something\otherfile.txt
파일 경로를 읽고 분할할 수 있음:
>>> for i in open("filedata.txt").readlines():
... print i.strip().split("\\")
...
['d:', 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt']
['d:', 'otherstuff', 'something', 'otherfile.txt']
re.properties는 끈보다 조금 더 많은 것을 도울 수 있다.
import re
var = "d:\stuff\morestuff\furtherdown\THEFILE.txt"
re.split( r'[\\/]', var )
['d:', 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt']
Linux 및 Mac 경로도 지원하려면 필터(None, result)를 추가하기만 하면 된다. 따라서 해당 경로가 '//' 또는 '//'로 시작되므로 분할()에서 원하지 않는 ''을(를) 제거한다(예: '/mount/...' 또는 '/var/tmp/').
import re
var = "/var/stuff/morestuff/furtherdown/THEFILE.txt"
result = re.split( r'[\\/]', var )
filter( None, result )
['var', 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt']
코드 라인의 아래는 다음을 처리할 수 있다.
- C:/경로/경로
- C://경로//경로
- C:\path\path
- C:\path\path
경로 = re.properties(r'[///\], 경로)
재미로 재귀 한번.
가장 우아한 대답은 아니지만 어디에서나 효과가 있어야 한다.
import os
def split_path(path):
head = os.path.dirname(path)
tail = os.path.basename(path)
if head == os.path.dirname(head):
return [tail]
return split_path(head) + [tail]
@Mike Robins의 솔루션을 개조하여 처음부터 빈 경로 요소를 피하십시오.
def parts(path):
p,f = os.path.split(os.path.normpath(path))
return parts(p) + [f] if f and p else [p] if p else []
os.path.normpath()
실제로 한 번만 필요하며, 재귀에 대한 별도의 입력 기능으로 수행될 수 있다.
이것이 질문에 대한 해답이 될지는 모르겠지만, 스택을 유지하고, os.path 기반 조작을 고수하며, 항목의 목록/스택을 반환하는 이 작은 기능을 쓰면서 즐거운 시간을 보냈다.
def components(path):
ret = []
while len(path) > 0:
path, crust = split(path)
ret.insert(0, crust)
return ret
from os import path as os_path
그 다음에
def split_path_iter(string, lst):
head, tail = os_path.split(string)
if head == '':
return [string] + lst
else:
return split_path_iter(head, [tail] + lst)
def split_path(string):
return split_path_iter(string, [])
또는 위의 답변(더 우아함):
def split_path(string):
head, tail = os_path.split(string)
if head == '':
return [string]
else:
return split_path(head) + [tail]
아쉽다! python os.path에는 os.path.splitall 같은 것이 없다.
어쨌든, 이것은 나에게 효과가 있다. 신용: https://www.oreilly.com/library/view/python-cookbook/0596001673/ch04s16.html
import os
a = '/media//max/Data/'
def splitall(path):
# https://www.oreilly.com/library/view/python-cookbook/0596001673/ch04s16.html
allparts = []
while 1:
parts = os.path.split(path)
if parts[0] == path: # sentinel for absolute paths
allparts.insert(0, parts[0])
break
elif parts[1] == path: # sentinel for relative paths
allparts.insert(0, parts[1])
break
else:
path = parts[0]
allparts.insert(0, parts[1])
return allparts
x = splitall(a)
print(x)
z = os.path.join(*x)
print(z)
출력:
['/', 'media', 'max', 'Data', '']
/media/max/Data/
사용하다ntpath.split()
참조URL: https://stackoverflow.com/questions/3167154/how-to-split-a-dos-path-into-its-components-in-python
'IT이야기' 카테고리의 다른 글
nuxt 라우터 모듈의 router.js 파일에서 Vuex 저장소에 액세스하는 방법? (0) | 2022.04.01 |
---|---|
vuex에서 작업을 생성하는 올바른 방법 (0) | 2022.04.01 |
리액션 구성 요소를 부모 구성 요소와 비교하여 배치하는 방법? (0) | 2022.04.01 |
vue js에서 특정 구성 요소로 리디렉션하는 방법 (0) | 2022.04.01 |
Ract Router에서 브라우저 기록 푸시를 사용할 때 경로 매개 변수를 전달하는 방법 (0) | 2022.04.01 |