Что нового

Деление пути к файлу на части

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Функция позволяет получить массив с разными элементами в пути к файлу:

Возвращаемый массив:
Код:
[0] = Исходный путь
[1] = Имя диска
[2] = Путь без имени и расширения файла
[3] = Путь бз расширения файла
[4] = Путь без имени диска
[5] = Имя файла и его расширение
[6] = Имя файла
[7] = Только расширение файла

Код:
;Автор: CreatoR
;Деление пути на части:
;имя диска, путь без имени и расширения файла, путь бз расширения, путь без имени диска,
;имя файла и расширение, имя файла, только расширение файла

#include <Array.au3> ;Только для примера

$sPath = "C:\Test\My Folder\File.zip"
$aPathArr = _PathSplitByRegExp($sPath)

If IsArray($aPathArr) Then
	_ArrayDisplay($aPathArr, "Demo of _PathSplitRegExp()")
ElseIf $aPathArr = $sPath Then
	MsgBox(64, "Demo of _PathSplitRegExp()", $aPathArr)
Else
	MsgBox(48, "Error", "The path is not correct")
EndIf

;===============================================================================
; Function Name:    _PathSplitByRegExp()
; Description:      Split the path to 8 elements.
; Parameter(s):     $sPath - Path to split.
; Requirement(s):   
; Return Value(s):  On seccess - Array $aRetArray that contain 8 elements:
;					$aRetArray[0] = Full path ($sPath)
;					$aRetArray[1] = Drive letter
;					$aRetArray[2] = Path without FileName and extension
;					$aRetArray[3] = Full path without File Extension
;					$aRetArray[4] = Full path without drive letter
;					$aRetArray[5] = FileName and extension
;					$aRetArray[6] = Just Filename
;					$aRetArray[7] = Just Extension of a file
;
;					On failure - If $sPath not include correct path (the path is not splitable),
;					then $sPath returned.
;					If $sPath not include needed delimiters, or it's emty,
;					then @error set to 1, and returned -1.
;
; Note(s):			The path can include backslash as well (exmp: C:/test/test.zip).
;
; Author(s):        G.Sandler a.k.a CreatoR (MsCreatoR) - Thanks to amel27 for help with RegExp
;===============================================================================
Func _PathSplitByRegExp($sPath)
	If $sPath = "" Or (StringInStr($sPath, "\") And StringInStr($sPath, "/")) Then Return SetError(1, 0, -1)
    
	Local $aRetArray[8], $pDelim = ""
	
	If StringRegExp($sPath, '^(?i)([A-Z]:|\\)(\\[^\\]+)+$') Then $pDelim = "\"
	If StringRegExp($sPath, '(?i)(^.*:/)(/[^/]+)+$') Then $pDelim = "//"
	
	If $pDelim = "" Then $pDelim = "/"
	If Not StringInStr($sPath, $pDelim) Then Return $sPath
	If $pDelim = "\" Then $pDelim &= "\"
	
	$aRetArray[0] = $sPath ;Full path
	$aRetArray[1] = StringRegExpReplace($sPath,  $pDelim & '.*', $pDelim) ;Drive letter
	$aRetArray[2] = StringRegExpReplace($sPath, $pDelim & '[^' & $pDelim & ']*$', '') ;Path without FileName and extension
	$aRetArray[3] = StringRegExpReplace($sPath, '\.[^.]*$', '') ;Full path without File Extension
	$aRetArray[4] = StringRegExpReplace($sPath, '(?i)([A-Z]:' & $pDelim & ')', '') ;Full path without drive letter
	$aRetArray[5] = StringRegExpReplace($sPath, '^.*' & $pDelim, '') ;FileName and extension
	$aRetArray[6] = StringRegExpReplace($sPath, '.*' & $pDelim & '|\.[^.]*$', '') ;Just Filename
	$aRetArray[7] = StringRegExpReplace($sPath, '^.*\.', '') ;Just Extension of a file
	
	Return $aRetArray
EndFunc
 

Medic84

Омега
Команда форума
Администратор
Сообщения
1,590
Репутация
341
Ошибка в 7 элементе массива. Если у файла нет расширения - то выводит полный путь.
Код:
[0]|C:\Users\Дмитрий\Dropbox\WorK\VC#\AutoIT Project Manager 2\AutoIT Project Manager 2\bin\Release
[1]|C:\
[2]|C:\Users\Дмитрий\Dropbox\WorK\VC#\AutoIT Project Manager 2\AutoIT Project Manager 2\bin
[3]|C:\Users\Дмитрий\Dropbox\WorK\VC#\AutoIT Project Manager 2\AutoIT Project Manager 2\bin\Release
[4]|Users\Дмитрий\Dropbox\WorK\VC#\AutoIT Project Manager 2\AutoIT Project Manager 2\bin\Release
[5]|Release
[6]|Release
[7]|C:\Users\Дмитрий\Dropbox\WorK\VC#\AutoIT Project Manager 2\AutoIT Project Manager 2\bin\Release
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Medic84 [?]
Если у файла нет расширения - то выводит полный путь
Добавь «?» после точки на конце шаблона.

На самом деле эту функцию нужно переписать, она не работает с UNC путями.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
Вот изменённая функция Gibbo:

Код:
#include <Array.au3> ;Only for the example

$sPath = @ScriptFullPath
$aPath = _PathSplitByRegExp($sPath)
_ArrayDisplay($aPath, "Demo of _PathSplitRegExp()")

; #FUNCTION# ====================================================================================================
; Name...........:	_PathSplitByRegExp
; Description....:	Splits the path to 5 elements.
; Syntax.........:	_PathSplitByRegExp($sPath)
; Parameters.....:	$sPath - Path to split.
;					
; Return values..:	Success - Array that contain 5 elements:
;																			[0] = Original path ($sPath)
;																			[1] = Drive
;																			[2] = Directory
;																			[3] = File name
;																			[4] = Extension
;					Failure - Returns 0 and sets @error as following:
;																			1 - $sPath is not a valid path (the path is not splitable).
;																			2 - Array is invalid. No matches.
;																			3 - [Should not happen] Bad pattern, array is invalid. @Extended = offset of error in pattern.
; Author.........:	Gibbo, Mod. by G.Sandler a.k.a (Mr)CreatoR.
; Modified.......:	
; Remarks .......:	* The path can include backslash as well (exmp: C:/test/test.zip).
;					* This function does not take a command line string. It works on paths, not paths with arguments.
;                 	* This differs from _PathSplit in that the drive letter or servershare retains the "" not the path.
;                 	* RegEx Built using examples from "Regular Expressions Cookbook (O’Reilly Media, 2009)"
; Related........:	
; Link...........:	
; Example........:	Yes.
; ===============================================================================================================
Func _PathSplitByRegExp($sPath)
	If StringStripWS($sPath, 8) = '' Then
		Return SetError(1, 0, 0)
	EndIf
	
	$sPath = StringReplace($sPath, '/', '\')
	
	Local $aRet = StringRegExp($sPath, '^(?i)([a-z]:|\\\\(?:\?\\)?[a-z0-9_.$]+\\[a-z0-9_.]+\$?)?(\\(?:[^\\/:*?"<>|\r\n]+\\)*)?([^\\/:*?"<>|\r\n.]*)\.?((?:[^.\\/:*?"<>|\r\n]+)?)$', 2)
	
	Switch @error
        Case 1
            Return SetError(2, 0, 0) ;Array is invalid. No matches.
        Case 2
			Return SetError(3, @extended, 0) ;Bad pattern, array is invalid. @Extended = offset of error in pattern.
	EndSwitch
	
	Return $aRet
EndFunc


Возвращает массив с 5-ю элементами:
Код:
[0] = Исходный путь ($sPath)
[1] = Диск
[2] = Папка
[3] = Имя файла
[4] = Расширение
 

glax24

Знающий
Сообщения
72
Репутация
14
более новая версия функции http://www.autoitscript.com/forum/topic/41897-pathsplitbyregexp/

Как доработать функцию чтобы возвращала еще и параметры командной строки если они есть
например строка
Код:
"C:\Program Files\Microsoft Security Client\msseces.exe" -hide -runkey
И функция возвращала
Код:
C:\Program Files\Microsoft Security Client\msseces.exe
C:\
C:\Program Files\Microsoft Security Client
C:\Program Files\Microsoft Security Client\msseces
Program Files\Microsoft Security Client\msseces.exe
Program Files\Microsoft Security Client
msseces.exe
msseces
exe 
-hide -runkey
 

Astel064

Помог мой пост, ставь +!
Сообщения
276
Репутация
51
Может это поможет? (см. прикрепленный файл)
 

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
Astel064
интересные примеры.
хотя можно сделать небольшие упрощения. например
Код:
Func _PuthEx_EndName($FilePuth); получаем имя файла с расширением из полного пути к нему
Local $Split = StringSplit ( $FilePuth, "\" )
If $Split[0] = 0 Then Return $FilePuth
;	For $i = $Split[0] To $Split[0]
;	Return $Split[$i]
;	Next
Return $Split[$Split[0]]
EndFunc

то есть перебор не нужен
 

Astel064

Помог мой пост, ставь +!
Сообщения
276
Репутация
51
то есть перебор не нужен
Спасибо за подсказку, но я что-то подобное пробовал ранее (давно) сделать и все завершилось ошибкой, после чего я начал делать перебор
 

AZJIO

Меценат
Меценат
Сообщения
2,892
Репутация
1,196
Astel064
Использую _FO_PathSplit потому что оптимизировал и по скорости выполнения и по часто используемых возвращаемых данных и по некритичности к содержимому. Возвращает ожидаемое. Вообще каждый раз надо делать отдельный вариант для каждого случая, потому что зная возможные варианты возврата можно более точно исключить ошибки, более кратко написать не проверяя то что никогда не случится. Но хорошо иметь список регулярных выражений, как в вышеуказанных функциях, просто выбираешь на данный момент необходимое и используешь только её, а не весь комбайн.
 
Сообщения
142
Репутация
-3
Напишите регулярное выражение для варианта "только директория, без имени файла и расширения". У меня вышло, что там
Код:
\[^\]*$
но в тесте ничего не ищет.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,486
ЭйчЭйч [?]
выражение для варианта "только директория, без имени файла и расширения". У меня вышло, что там
В регулярных выражениях у спец. символов (типа \) должен быть префикс \.
Код:
\\[^\\]*$
 
Верх