Jump to content
Sign in to follow this  
Gibbo

_PathSplitRegEx

Recommended Posts

Gibbo

Recently I had the need to split paths like _PathSplit outside of AutoIt.

Regular expressions seemed to be the way to go and it was fun to learn a bit more about their power.

I backported it to AutoIt and now use it instead of _PathSplit.

This should match any combination of:

servershare[$] | Drive
path
filename
.extention

Some caveats:

It only returns an array (returning strings via byref aswell seemed a tad overkill / messy)

The Drive letter retains its trailing "" NOT the path (this seemed more sane as the path should be relative not anchored to the root of the drive) - Found that this was not so good for things like "C:" as the path shoud be set to "" not nothing

; #FUNCTION# ====================================================================================================================
; Name...........: _PathSplitRegEx
; Description ...: Splits a path into the drive, directory, file name and file extension parts. An empty string is set if a part is missing.
; Syntax.........: _PathSplitRegEx($sPath)
; Parameters ....: $sPath - The path to be split (Can contain a UNC server or drive letter)
; Return values .: Success - Returns an array with 5 elements where 0 = original path, 1 = drive, 2 = directory, 3 = filename, 4 = extension
; Author ........: Gibbo
; Modified.......:
; Remarks .......: 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 .......: _PathSplit, _PathFull, _PathMake
; Link ..........:
; Example .......: Yes
; ===============================================================================================================================
Func _PathSplitRegEx($sPath)
if $sPath="" then Return SetError(1,0,"")
Local Const $rPathSplit = '^(?i)([a-z]:|[a-z0-9_.$]+[a-z0-9_.]+$?)?((?:[^/:*?"<>|rn]+)*)?([^/:*?"<>|rn.]*)((?:.[^./:*?"<>|rn]+)?)$'
Local $aResult = StringRegExp($sPath, $rPathSplit, 2)
Switch @error
Case 0
Return $aResult
Case 1
Return SetError(2, 0, "")
Case 2
;This should never happen!
EndSwitch
EndFunc ;==>_PathSplitRegEx

Anyhow, I hope someone else finds this useful :D

Edit: @ScriptFullPath replaced with the parameter $sPath - Thanks czardas. Should have reread before posting.

Edit2: Changed regex to move the trailing "" from the "root" to the begining of the path.

Edit3: Edit destroyed the regex (why??) added below as well in plain code tags just in case it happens again:

Local Const $rPathSplit = '^(?i)([a-z]:|[a-z0-9_.$]+[a-z0-9_.]+$?)?((?:[^/:*?"<>|rn]+)*)?([^/:*?"<>|rn.]*)((?:.[^./:*?"<>|rn]+)?)$'
Edited by Gibbo
  • Like 1

Share this post


Link to post
Share on other sites
czardas

There appears to be an editing msitake in this function. @ScriptFullPath needs to be replaced with the parameter $sPath , it's the sort of thing I might overlook myself during testing. Not examined it in detail, but it seems to be working.

Edited by czardas

Share this post


Link to post
Share on other sites
MrCreatoR
  • Like 1

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites
Gibbo

@czardas - Thanks for picking that up :D

@MrCreatoR

I took a look and tested:

#include <File.au3>
#include <Array.au3>
$aSplit = _PathSplitByRegExp("serversharepathfile.ext")
_ArrayDisplay($aSplit)

$aSplit = _PathSplitRegEx("serversharepathfile.ext")
_ArrayDisplay($aSplit)

Local $szDrive, $szDir, $szFName, $szExt
Local $TestPath = _PathSplit("serversharepathfile.ext", $szDrive, $szDir, $szFName, $szExt)
_ArrayDisplay($TestPath, "Demo _PathSplit()")

Yours seems to fail on UNC paths

[0]|serversharepathfile.ext
[1]|
[2]|serversharepath
[3]|serversharepathfile
[4]|serversharepathfile.ext
[5]|serversharepath
[6]|file.ext
[7]|file
[8]|ext

Also returning all those combinations seems a bit of overkill considering any of those could be reconstructed from just "root,folder,file,ext" :huh:

[0]|serversharepathfile.ext
[1]|servershare
[2]|path
[3]|file
[4]|.ext

Mine groups the share with the server name as this is the "root" of any folder structure in a share.

[0]|serversharepathfile.ext
[1]|server
[2]|sharepath
[3]|file
[4]|.ext

_PathSplit does a good job but groups the share name with the path and I didn't much care for all the "ByRef" strings and such when $aSplit[0] -> $aSplit[4] already contained the values.

All up though it was more of a fun exercise to make/port. I found it useful and just thought others would too.

:)

Share this post


Link to post
Share on other sites
MrCreatoR

I took a look and tested:

Your function does not return an array, and what shouldn't never happen, happened:

#include <Array.au3>

$aSplit = _PathSplitRegEx("serversharepathfile.ext")
_ArrayDisplay($aSplit)

Func _PathSplitRegEx($sPath)
    if $sPath="" then Return SetError(1,0,"")
    Local Const $rPathSplit = '^(?i)([a-z]:|[a-z0-9_.$]+[a-z0-9_.]+$?)?((?:[^/:*?"<>|rn]+)*)?([^/:*?"<>|rn.]*)((?:.[^./:*?"<>|rn]+)?)$'
    Local $aResult = StringRegExp($sPath, $rPathSplit, 2)
    Switch @error
        Case 0
            Return $aResult
        Case 1
            Return SetError(2, 0, "")
        Case 2
            MsgBox(64, 'Title', 'This should never happen? Well, it''s happened :)')
    EndSwitch
EndFunc

:)

Edited by MrCreatoR

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites
Gibbo

The reason it didn't work for you is that the forums seem to have destroyed the regex

I had:

Local Const $rPathSplit = '^(?i)([a-z]:|\\\\[a-z0-9_.$]+\\[a-z0-9_.]+\$?)?(\\(?:[^\\/:*?"<>|\r\n]+\\)*)?([^\\/:*?"<>|\r\n.]*)((?:\.[^.\\/:*?"<>|\r\n]+)?)$'

You used:

Local Const $rPathSplit = '^(?i)([a-z]:|[a-z0-9_.$]+[a-z0-9_.]+$?)?((?:[^/:*?"<>|rn]+)*)?([^/:*?"<>|rn.]*)((?:.[^./:*?"<>|rn]+)?)$'

Share this post


Link to post
Share on other sites
Quual

So often I find that I only need part of the filename, ie, just the ext, or just the Drive, so I created these fairly simple functions.

Func File_GetDrive($sFilespec)
    Return StringRegExpReplace($sFilespec, '^([A-Za-z]:)?(?:.*)$', '1')
EndFunc
Func File_GetPath($sFilespec)
    If Not StringRegExp($sFilespec, "", 0) Then Return ''
    Return StringRegExpReplace($sFilespec, '^([A-Za-z]:|[A-Za-z]:||)(.*)?(?:[^]+)?$', '2')
EndFunc
Func File_GetName($sFilespec)
    If StringRegExp($sFilespec, "$", 0) Then Return ''
    Return StringRegExpReplace($sFilespec, '^(?:[A-Za-z]:|)(?:.*|)(.*?)(?:.[^.]*|)$', '1')
EndFunc
Func File_GetExt($sFilespec)
    If StringRegExp($sFilespec, "$", 0) Or Not StringRegExp($sFilespec, ".", 0) Then Return ''
    Return StringRegExpReplace($sFilespec, '^(?:[A-Za-z]:|)(?:.*|)(?:.*?)(.[^.]*)?$', '1')
EndFunc
Func File_GetDriveAndPath($sFilespec)
    Return StringRegExpReplace($sFilespec, '^([A-Za-z]:|)(?:|)(.*|)(?:[^]*)', '12')
EndFunc
Func File_GetNameAndExt($sFilespec)
    Return StringRegExpReplace($sFilespec, '^(?:[A-Za-z]:|.*|)([^.].*)?(.[^.]*)?$', '1')
EndFunc
Func File_GetParent($sFilespec)
    Local $vParts = StringRegExp($sFilespec,"(.*)([^]+?)$",3)
    If Not @error Then Return $vParts[0]
EndFunc
Func Win_FilenameSafe($sFilespec)
    Return StringRegExpReplace($sFilespec,"x00|x01|x02|x03|x04|x05|x06|x07|x08|x09|x0A|x0B|x0C|x0D|x0E|x0F|x10|x11|x12|x13|x14|x15|x16|x17|x18|x19|x1Ax1B|x1C|x1D|x1E|x1F|x22|x2A|x2F|x3A|x3C|x3E|x3F|x5C|x7C|x81|x8D|x8F|x90|x9D|xAD","")
EndFunc

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Similar Content

    • milkmoron
      By milkmoron
      I am trying to search in a web browser dates XX/XX/XXXX that are also links. I want to click them after and remove them from the array. This is all I have so far. Nothing shows up. What am I doing wrong?
      ControlFocus ("Customer Center", "", "")
      Local $aArray = StringRegExp('(..)/(..)/(....)', '(..)/(..)/(....)', $STR_REGEXPARRAYFULLMATCH)
      For $i = 0 To UBound($aArray) - 1
          MsgBox($MB_SYSTEMMODAL, "RegExp Test with Option 2 - " & $i, $aArray[$i])
      Next
       
    • WoodGrain
      By WoodGrain
      Hi All,
      I'd like to replace 'COMMA' with ',' for example:
      $myString = "COMMA" StringRegExpReplace($myString, 'COMMA', ',') Now I've tried escaping the ',' in various ways unsuccessfully, such as:
      '[,]'
      "[,]"
      '\,'
      [,] seems to work in the pattern, I just can't figure out how to use it in the replace, and it seems everyone online is only interested in removing/replacing commas lol.
      I also tried creating and using a variable as the replacement but also didn't work:
      $myComma = "," $myString = "COMMA" StringRegExpReplace($myString, 'COMMA', $myComma) I'm sure it's super simple if someone could point me in the right direction - thanks.
    • rcmaehl
      By rcmaehl
      Hi all,
      I still suck at regex as always and I need some help. According to the regex tester I normally use this should be working fine but it doesn't....
      StringRegExp($sString, "\A[1-9]+[0-9]*(\-[1-9]+[0-9]*)?,*\Z") I basically want to match:
      all numbers EXCEPT 0, but including 10, 20, etc with each number separated by a comma and allowing a "-" separated range as a value For example:
      1-5,7,10-12 I've spent a couple hours modifying it but I'm not sure where I've gone wrong. Any help would be appreciated!
    • ISI360
      By ISI360
      Hi!

      I need a little bit help from some RegEx experts please:
      I would make my ISN AutoIt Studio faster when generating the scripttree. And what would be better to do this via regex?
      Problem is i am not really good at this regex stuff. So maybe someone could help me here.
       
      The challange is to get all Global Variables from a script via RegEx in a Array.
      Here is a example script with some tests:
      Global $Var1 = 1234 Local $Local_Var = 1234 $Ignore_me_too = 1234 Global $Var2 = 1234, $var3 = 1242 Global $ahIcons[30], $ahLabels[30] Global Const $Var4 = iniread($inivar1,"jj","jj","") , $var5= iniread($inivar2,"jj","jj","") Global $Var_String = "was" Global $Array_Test[16] = [1,15,16,0,31,15,25,15,25,30,8,30,8,15,1,15] Global Enum $MARGIN_SCRIPT_NUMBER = 0, $MARGIN_SCRIPT_ICON, $MARGIN_SCRIPT_FOLD Global Const $Delim = '\', $Delim1 = '|' Global $hard1 = "a", _ $hard2 = "b", _ $hard3 = "c"  
      The returning array should look like this:
      $Var1 $Var2 $var3 $Var4 $var5 $Var_String $Array_Test $MARGIN_SCRIPT_NUMBER $MARGIN_SCRIPT_ICON $MARGIN_SCRIPT_FOLD $Delim $Delim1 $hard1 $hard2 $hard3  
      I already made some success with a expression i found in the SciTE Jump Tool:  (\$\w+)(?:[\h\[.=+*/^,)\-])?
      This nearly returns the perfect results. But it does not check if it´s a global variable (with the const and enum options) and also returns variables in commands (for example $inivar1)
      I also found this regex: (?im:^(?=Global|Const|Enum|Static)(?:Global)?\h*(?:Const|Enum|Static)?(?:(?<=Enum)\h+Step\h+[+*-]\d+)?\h*)([^\r\n .\=]+)
      This returns also usefull results...but trying to understand this explodes my head

      Maybe someone can help me here?
      Thanks in advance!
    • TheAutomator
      By TheAutomator
      Can anyone tell me why this isn't working?..
      #include <array.au3> $regexp = StringRegExp("test 'a b c'", "'([^']|'')*'|\S+", 3) _ArrayDisplay($regexp) trying to split this "test 'a b c'  'some other '' test'' ...'" into:
      0: test
      1: 'a b c'
      2: ...
      but it gives me:
      0: test
      1: c
×