Что нового

Файловая система Функции для обработки путей к файлам или папкам.

IMStrelcov

CTPEJIbLLOB
Сообщения
253
Репутация
64
Версия AutoIt
3.3.14.5
Версия
0.1
МОЖЕТ КОМУ БУДЕТ ПОЛЕЗНЫМ.

Мои функции для работы с путями к файлам или папкам.
Функции старался делать как можно компактнее и чтобы работали быстрее аналогов.
Код:
;################################################################################
;
; Описание......:    добавить в конец пути "\" если ее нет
;
; Синтаксис.....:    Path_AddSlash_($_sPath)
;
; Параметры.....:    $_sPath = путь к файлу/папке
;
; Результат.....:    возвращает путь с "\" в конце
;
; Примечание....:    рекомендуется указывать в $_sPath правильный путь
;
;################################################################################
Func Path_AddSlash_($_sPath)
   Return StringRegExp($_sPath, '^(.*?)(?:\\+)?$', 3)[0]& '\'
EndFunc





;################################################################################
;
; Описание......:    удалить в конце пути "\"
;
; Синтаксис.....:    Path_DelSlash_($_sPath)
;
; Параметры.....:    $_sPath = путь к файлу/папке
;
; Результат.....:    возвращает путь без "\" в конце
;
; Примечание....:    рекомендуется указывать в $_sPath правильный путь
;
;################################################################################
Func Path_DelSlash_($_sPath)
   Return StringRegExp($_sPath, '^(.*?)(?:\\+)?$', 3)[0]
EndFunc





;################################################################################
;
; Описание......:    получить из пути, путь без имени и типа (если есть) файла/папки
;
; Синтаксис.....:    Path_GetPath_($_sPath)
;
; Параметры.....:    $_sPath = путь к файлу/папке
;
; Результат.....:    возвращает путь без имени и типа (если есть) файла/папки
;
; Примечание....:    рекомендуется указывать в $_sPath правильный путь
;
;################################################################################
Func Path_GetPath_($_sPath)
   Return StringRegExp($_sPath, '^(.*?\\)?[^\\]*\\?$', 3)[0]
EndFunc





;################################################################################
;
; Описание......:    удалить из пути диск
;
; Синтаксис.....:    Path_GetSubPath_($_sPath)
;
; Параметры.....:    $_sPath = путь к файлу/папке
;
; Результат.....:    возвращает путь без диска
;
; Примечание....:    рекомендуется указывать в $_sPath правильный путь
;
;                    "\" в начале $_sPath будет считаться диском
;
;################################################################################
Func Path_GetSubPath_($_sPath)
   Return StringRegExp($_sPath, '^(?:(?:.:)?\\?)?([^\\]?.*)?', 3)[0]
EndFunc





;################################################################################
;
; Описание......:    получить из пути диск
;
; Синтаксис.....:    Path_GetDrive_($_sPath)
;
; Параметры.....:    $_sPath = путь к файлу/папке
;
; Результат.....:    возвращает диск
;
; Примечание....:    рекомендуется указывать в $_sPath правильный путь
;
;                    "\" в начале $_sPath будет считаться диском
;
;################################################################################
Func Path_GetDrive_($_sPath)
   Return StringRegExp($_sPath, '^((?:.:)?\\?)?', 3)[0]
EndFunc





;################################################################################
;
; Описание......:    получить из пути имя и тип (если есть) файла/папки
;
; Синтаксис.....:    Path_GetFile_($_sPath)
;
; Параметры.....:    $_sPath = путь к файлу/папке
;
; Результат.....:    возвращает имя и тип (если есть) файла/папки
;
; Примечание....:    рекомендуется указывать в $_sPath правильный путь
;
;################################################################################
Func Path_GetFile_($_sPath)
   Return StringRegExp($_sPath, '([^\\]+\\?)?$', 3)[0]
EndFunc





;################################################################################
;
; Описание......:    получить из пути имя файла
;
; Синтаксис.....:    Path_GetFileName_($_sPath)
;
; Параметры.....:    $_sPath = путь к файлу/папке
;
; Результат.....:    возвращает имя файла
;
; Примечание....:    рекомендуется указывать в $_sPath правильный путь
;
;                    если $_sPath заканчивается косой чертой "\"
;                    то это будет считаться папкой, а не файлом
;
;################################################################################
Func Path_GetFileName_($_sPath)
   Return StringRegExp($_sPath, '([^\\]*?)?(?(?=\.[^\h\.\\]+)\.[^\h\.\\]*)$', 3)[0]
EndFunc





;################################################################################
;
; Описание......:    получить из пути тип файла
;
; Синтаксис.....:    Path_GetFileType_($_sPath)
;
; Параметры.....:    $_sPath = путь к файлу/папке
;
; Результат.....:    возвращает тип файла
;
; Примечание....:    рекомендуется указывать в $_sPath правильный путь
;
;                    если $_sPath заканчивается косой чертой "\"
;                    то это будет считаться папкой, а не файлом
;
;################################################################################
Func Path_GetFileType_($_sPath)
   Return StringRegExp($_sPath, '(\.[^\h\.\\]+)?$', 3)[0]
EndFunc





;################################################################################
;
; Описание......:    создает полный абсолютный путь на основе относительного пути
;
; Синтаксис.....:    Path_GetFullPath_($_sPath [, $_sBase = @WorkingDir])
;
; Параметры.....:    $_sPath = относительный путь к диску/папке/файлу,
;                        может начинаться как с диска так и с имени папки/файла,
;                        или косой черты (рабочий диск), или одной (рабочая папка)
;                        и двух (папка назад) точек с косой чертой
;
;                    $_sBase = базовый путь, который будет использоваться,
;                        может быть или полный путь к каталогу,
;                        или буква диска с двоеточием
;
; Результат.....:    возвращает полный абсолютный путь к диску/папке/файлу,
;
; Примечание....:    рекомендуется указывать в $_sPath правильный путь
;                    рекомендуется указывать в $_sBase полный, правильный путь
;
;                    в $_sPath, начале пути может быть как "диск",
;                    так и "\" = рабочий диск, ".\" = путь к рабочему каталогу,
;                    так же могут быть "..\" = каталогом назад
;
;################################################################################
Func Path_GetFullPath_($_sPath, $_sBase = @WorkingDir)
   If Not StringRegExp($_sBase, '(^[[:alpha:]]:)') Then $_sBase = @WorkingDir
   $_sBase = StringRegExp($_sBase, '(.*?)\\*$', 3)[0]& '\'
   If StringRegExp($_sPath, '(^\\)') Then
      $_sPath = StringRegExp($_sBase, '^.', 3)[0]& ':'& $_sPath
   ElseIf Not StringRegExp($_sPath, '(^[[:alpha:]]:)') Then
      $_sPath = $_sBase& StringRegExp($_sPath, '^(?(?!\.\.)\.?\\?)(.*)?', 3)[0]
   EndIf
   $_aPath = StringRegExp($_sPath, '([^\\]+\\?|\\|^$)', 3)
   $_sPath = ''
   For $_sText In $_aPath
      If StringRegExp($_sText, '(^\.{2}(\\|$))') Then
         $_sPath = StringRegExp($_sPath, '^(([^\\]+\\)+)?[^\\]+?\\?$', 3)[0]
      Else
         $_sPath &= $_sText
      EndIf
   Next
   Return $_sPath
EndFunc





;################################################################################
;
; Описание......:    исправляет правильность написания пути к диску/папке/файлу,
;                    удаляя не допустимые символы и имена папок/файлов
;
; Синтаксис.....:    Path_Corrections_($_sPath)
;
; Параметры.....:    $_sPath = путь к диску/папке/файлу, который нужно исправить
;
; Результат.....:    возвращает исправленный путь к диску/папке/файлу
;
; Примечание....:    в $_sPath, начале пути может быть как "диск",
;                    так и "\" = рабочий диск, ".\" = путь к рабочему каталогу,
;                    так же могут быть "..\" = каталогом назад
;
;################################################################################
Func Path_Corrections_($_sPath)
   $_sPath = StringRegExpReplace($_sPath, '(?ixs)([*?"<>\v\t]+)', '')
   $_sPath = StringRegExpReplace($_sPath, '(?ixs)([\\|/]+)', '\\')
   $_sPath = StringRegExpReplace($_sPath, '(?ixs)^[:\.\h]*([[:alpha:]])[\.\h]*:[:\.\h]*\\?', '$1:\\')
   $_sPath = StringRegExpReplace($_sPath, '(?ixs)(?(?<!^[[:alpha:]]):)', '')
   $_sPath = StringRegExpReplace($_sPath, '(?ixs) ([^\h\.\\])[\h\.]+(\\|$)', '$1$2')
   $_sPath = StringRegExpReplace($_sPath, '(?ixs) (?(?<=\\)(\.(\h[\h\.]*)?|\.{2}[\h\.]+|\h+[\h\.]*)(\\|$))', '')
   $_sPath = StringRegExpReplace($_sPath, '(?ixs) ^(\.(\h[\h\.]*)|\.{2}[\h\.]+|\h+[\h\.]*)(\\|$)', '')
   Return $_sPath
EndFunc





;################################################################################
;
; Описание......:    Генерирует новое имя папки/файла, если он уже существует,
;                    так как это делает винда, добавляя к имени номер в скобках
;
; Синтаксис.....:    Path_SetPrefix_($_sPath [, $_iPrefix = 2])
;
; Параметры.....:    $_sPath = путь к диску/папке/файлу
;
;                    $_iPrefix = с какого номера начать счет
;
; Результат.....:    возвращает путь к диску/папке/файлу с новым именем
;
; Примечание....:    рекомендуется указывать в $_sPath полный, правильный путь
;
;################################################################################
Func Path_SetPrefix_($_sPath, $_iPrefix = 2)
   While 1
      $_sPath = StringRegExpReplace($_sPath, '^(.*?)(?:\h\([0-9]+\))?(\.[^\h\.]+)?$', '$1 ('& $_iPrefix& ')$2')
      If Not FileExists($_sPath) Then ExitLoop
      $_iPrefix += 1
   WEnd
   Return $_sPath
EndFunc





;################################################################################
;
; Описание......:    проверяет правильность написания пути к диску/папке/файлу
;
; Синтаксис.....:    Path_IsCorrect_($_sPath)
;
; Параметры.....:    $_sPath = путь к диску/папке/файлу, который нужно проверить
;
; Результат.....:    возвращает 1 - если путь правильный
;
;################################################################################
Func Path_IsCorrect_($_sPath)
   Return StringRegExp($_sPath,  '(?ixs)^(([[:alpha:]]:|\.)?($|\\))?((([\.\h]*[^|\\/:*?"<>\.\h\v\t]+)+|\.{2})\\?)*$')
EndFunc





;################################################################################
;
; Описание......:    разделить путь на диск/папки/файл/тип
;
; Синтаксис.....:    Path_Split_($_sPath)
;
; Параметры.....:    $_sPath = путь который будет разделен
;
; Результат.....:    возвращает массив,
;                        [0] = $_sPath
;                        [1] = диск:\
;                        [2] = папки\
;                        [3] = файл
;                        [4] = .тип
;
; Примечание....:    рекомендуется указывать в $_sPath полный, правильный путь
;
;                    если $_sPath заканчивается косой чертой "\"
;                    то это будет считаться папкой, а не файлом
;
;                    если $_sPath начинается с косой черты "\"
;                    то "\" будет считаться диском
;
;################################################################################
Func Path_Split_($_sPath)
   Local $_aPath = StringRegExp($_sPath, '^((?:[[:alpha:]]:)?\\?)?((?:[^\\]+\\)*)(?:([^\\]*?)((?:\.[^\h\.]+)?))$', 2)
   If @error Then Dim $_aPath[5]
   Return $_aPath
EndFunc
 

Andrey_A

Продвинутый
Сообщения
319
Репутация
68
Можно и так сделать для работы со списком путей
Код:
Func Path_AddSlash_($_sPath)
   Return StringRegExp($_sPath, '^(.*?)(?:\\+)?$', 3)[0]& '\'
   ; Return StringRegExpReplace($sFile, '^(.*?)\\*$','$1\\',1)
   ; Return StringRegExpReplace($sFile, '(?m)^(.*?)\\*$','$1\\') ; для списка путей
EndFunc

Func Path_DelSlash_($_sPath)
   Return StringRegExp($_sPath, '^(.*?)(?:\\+)?$', 3)[0]
   ; Return StringRegExpReplace($_sPath, '^(.*?)\\*$','$1',1)
   ; Return StringRegExpReplace($_sPath, '(?m)^(.*?)\\*$','$1') ; для списка путей
EndFunc

Func Path_GetPath_($_sPath)
   Return StringRegExp($_sPath, '^(.*?\\)?[^\\]*\\?$', 3)[0]
   ; Return StringRegExpReplace($_sPath,'^(.*?\\)?[^\\]*\\?$','$1',1)
   ; Return StringRegExpReplace($_sPath,'(?m)^(.*?\\)?[^\\]*\\?$','$1') ; для списка путей
EndFunc

Func Path_GetSubPath_($_sPath)
   Return StringRegExp($_sPath, '^(?:(?:.:)?\\?)?([^\\]?.*)?', 3)[0]
   ; Return StringRegExpReplace($_sPath,'^(?:(?:.:)?\\?)?([^\\]?.*)?','$1',1)
   ; Return StringRegExpReplace($_sPath,'(?m)^(?:(?:.:)?\\?)?([^\\]?.*)?','$1') ; для списка путей
EndFunc

; и.т.д
 
Автор
IMStrelcov

IMStrelcov

CTPEJIbLLOB
Сообщения
253
Репутация
64
Можно, но только для списков, в случае с одной строкой, функция StringRegExpReplace() работает медленее чем StringRegExp().
 

Andrey_A

Продвинутый
Сообщения
319
Репутация
68
работает медленее
Это не совсем так:
Код:
$_sPath='E:\TC IMAGE\Utilities\Scripting\AutoIt\Include\'
  $n=100000
  $hTimer=TimerInit()
  For $j=1 To $n
    $sR=Path_AddSlash_2($_sPath)
  Next
  $iDiff1=TimerDiff($hTimer)/1000
  $hTimer2=TimerInit()
  For $j=1 To $n
    $sR=Path_AddSlash_1($_sPath)
  Next
  $iDiff2=TimerDiff($hTimer2)/1000
  MsgBox(4096,"Итого","1: ===>"&$iDiff1&"<="&@CRLF&"2: ===>"&$iDiff2&"<=")

Func Path_AddSlash_1($_sPath)
  Return StringRegExp($_sPath, '^(.*?)(?:\\+)?$', 3)[0]& '\'
EndFunc

Func Path_AddSlash_2($_sPath)
  Return StringRegExpReplace($_sPath, '^(.*?)\\*$','$1\\',1)
EndFunc

Сообщение автоматически объединено:

А так ещё быстрее, но это дело для любителей автоматизации
Код:
Global $StringRegExp=StringRegExp
  Global $StringRegExpReplace=StringRegExpReplace
  $_sPath='E:\TC IMAGE\Utilities\Scripting\AutoIt\Include\'
  $n=100000
  $hTimer=TimerInit()
  For $j=1 To $n
    $sR=Path_AddSlash_2($_sPath)
  Next
  $iDiff1=TimerDiff($hTimer)/1000
  $hTimer2=TimerInit()
  For $j=1 To $n
    $sR=Path_AddSlash_1($_sPath)
  Next
  $iDiff2=TimerDiff($hTimer2)/1000
  MsgBox(4096,"Итого","1: ===>"&$iDiff1&"<="&@CRLF&"2: ===>"&$iDiff2&"<=")

Func Path_AddSlash_1($_sPath)
  Return $StringRegExp($_sPath, '^(.*?)(?:\\+)?$', 3)[0]& '\'
EndFunc

Func Path_AddSlash_2($_sPath)
  Return $StringRegExpReplace($_sPath, '^(.*?)\\*$','$1\\',1)
EndFunc

Сообщение автоматически объединено:

Для списков можно вставить (?m) и скорость незаметна...
Код:
Func Path_AddSlash_2($_sPath)
  Return $StringRegExpReplace($_sPath, '^(?m)^(.*?)\\*$','$1\\')
EndFunc
 
Последнее редактирование:

Andrey_A

Продвинутый
Сообщения
319
Репутация
68
IMStrelcov, наверно зависит от железа или от системы, это видно даже если заменить функции наоборот - будет разный результат.
Я написал не в укор вам, а для разнообразия использования регулярных выражений.
Что касается "функции можно использовать через переменную", то я тоже не нашёл подробного перевода, но в какой-то версии это добавили, что позволяет неким образом кешировать регулярное выражение и при повторном его использовании поиск/замена происходит быстрее.
 

xXx

╚{■_■}╗
Меценат
Сообщения
248
Репутация
95
OffTop
Что касается "функции можно использовать через переменную", то я тоже не нашёл подробного перевода
Аналогично.

но в какой-то версии это добавили
В версии *3.3.10.0* много чего еще добавили.

при повторном его использовании поиск/замена происходит быстрее
Но это как посмотреть:
Код:
Global $fnStringRegExp = StringRegExp
Global $fnStringRegExpReplace = StringRegExpReplace
Global $hTimer[4], $iDiff[4], $n = 10000
Global $sPath2, $sPath1 = 'E:\AutoIt\Include\'
$sPath2 = $sPath1

$hTimer[0] = TimerInit()
For $j = 1 To $n
    ;$sPath1 &= $j
    $1 = StringRegExp($sPath1, '^(.*?)(?:\\+)?$', 3)[0] & '\'
Next
$iDiff[0] = TimerDiff($hTimer[0]) / 1000
ConsoleWrite('StringRegExp        = ' & $iDiff[0] & @LF) ; •••••••••• П Р О В Е Р К А ••••••••••

$hTimer[1] = TimerInit()
For $j = 1 To $n
    ;$sPath2 &= $j
    $2 = $fnStringRegExp($sPath2, '^(.*?)(?:\\+)?$', 3)[0] & '\'
Next
$iDiff[1] = TimerDiff($hTimer[1]) / 1000
ConsoleWrite('$fnStringRegExp        = ' & $iDiff[1] & @LF) ; •••••••••• П Р О В Е Р К А ••••••••••

$hTimer[2] = TimerInit()
For $j = 1 To $n
    ;$sPath1 &= $j
    $1 = StringRegExpReplace($sPath1, '^(.*?)\\*$','$1\\',1)
Next
$iDiff[2] = TimerDiff($hTimer[2]) / 1000
ConsoleWrite('StringRegExpReplace    = ' & $iDiff[2] & @LF) ; •••••••••• П Р О В Е Р К А ••••••••••

$hTimer[3] = TimerInit()
For $j = 1 To $n
    ;$sPath1 &= $j
    $1 = $fnStringRegExpReplace($sPath2, '^(.*?)\\*$','$1\\',1)
Next
$iDiff[3] = TimerDiff($hTimer[3]) / 1000
ConsoleWrite('$fnStringRegExpReplace    = ' & $iDiff[3] & @LF) ; •••••••••• П Р О В Е Р К А ••••••••••

Задействуйте закомментированные строки и результат может измениться.
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Конструкцию

StringRegExp($_sPath, '^(.*?\\)?[^\\]*\\?$', 3)[0]
Использовать можно, но осторожно. Если уверены во входящих данных, ибо код может вывалиться с ошибкой.
Использование функций через переменую хорошая фишка. Давненько использовал в проекте, часто повторялись одинаковые функции либо при условии нужно сделать выбор функции. Даешь короткие имена переменной и вперед
 

Oki

Продвинутый
Сообщения
452
Репутация
62
Код:
Func Path_GetPath_($_sPath)
   Return StringRegExp($_sPath, '^(.*?\\)?[^\\]*\\?$', 3)[0]
EndFunc
А это чем-то отличается от такого без регулярных выражений?
Код:
Func Path_GetPath_($sPath)
   $iPathLen = StringLen($sPath)
   Return StringTrimRight($sPath, $iPathLen - StringInStr($sPath, "\", 1, -1, $iPathLen - 1))
EndFunc
 
Верх