Sign in to follow this  
Followers 0
Gene

Help With Stringregexp

21 posts in this topic

#1 ·  Posted (edited)

I need to find all the sub-folders in a folder whose name follows the pattern below. I have read the help file on this. I understand all the words and read prose at a grade 18 level but I don't get RegExpressions... yet. :mellow: This is the first time I ever believed I needed one.

Pattern: c...c_nnnn-nnaaa-nn-aaa-nnaa-nnaaa

where c = any alpha-numeric character

------ ... = an unknown number of characters

------- a = any alpha character

------- n = any numeric digit

Edit:

Another way of seeing it perhaps more accurately is...

Pattern: logonname_year-MonNoMonName-DayNo-DayName-HourNo"Hr"-MinuteNo"Min"

Any help is appreciated.

Gene :)

PS. I'm hoping that if I see something meaningful to me as a regexp I'll be able to put it together.

Edited by Gene

[font="Verdana"]Thanks for the response.Gene[/font]Yes, I know the punctuation is not right...

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

I need to find all the sub-folders in a folder whose name follows the pattern below. I have read the help file on this. I understand all the words and read prose at a grade 18 level but I don't get RegExpressions... yet. :mellow: This is the first time I ever believed I needed one.

Pattern: c...c_nnnn-nnaaa-nn-aaa-nnaa-nnaaa

where c = any alpha-numeric character

------ ... = an unknown number of characters

------- a = any alpha character

------- n = any numeric digit

Edit:

Another way of seeing it perhaps more accurately is...

Pattern: logonname_year-MonNoMonName-DayNo-DayName-HourNo"Hr"-MinuteNo"Min"

Any help is appreciated.

Gene :)

PS. I'm hoping that if I see something meaningful to me as a regexp I'll be able to put it together.

Is this something like it would look like?

SmOke_N_2006-03March-31-Friday-00"Hr"-10"Min"

Edit: I mean exactly how it would show... Sorry, should have been more explicit in my question. Edited by SmOke_N

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Is this something like it would look like?

Edit: I mean exactly how it would show... Sorry, should have been more explicit in my question.

Good question.

It would look like: SmOke_N_2006-03Mar-31-Fri-00Hr-10Min or

regan_2006-03Mar-31-Fri-01Hr-23Min

Gene


[font="Verdana"]Thanks for the response.Gene[/font]Yes, I know the punctuation is not right...

Share this post


Link to post
Share on other sites

This code just check if this string exists:

;c...c_nnnn-nnaaa-nn-aaa-nnaa-nnaaa
$a = StringRegExp("regan_2006-03Mar-31-Fri-01Hr-23Min", _
                  "\a+?_\d{4}-\d{2}\a{3}-\d{2}-\a{3}-\d{2}\a{2}-\d{2}\a{3}")
MsgBox (0, "Found?", $a)

If you need retreive values, just place needed values in brackets and run StringRegExp with 1 flag.

For example, code below will return array with 3 elements, where will be name, year, and month.

$a = StringRegExp("regan_2006-03Mar-31-Fri-01Hr-23Min", _
                  "(\a+?)_(\d{4})-(\d{2}\a{3})-\d{2}-\a{3}-\d{2}\a{2}-\d{2}\a{3}", 1)
If @extended then MsgBox (0, "Found?", $a[0] & @CRLF & $a[1] & @CRLF & $a[2])

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Ha... Well, I couldn't figure it out quick enough for my taste, so I wrote this LOOOOOOOOOOONG function to do it.... (I'm sure you'll like the speed of the StringRegExp() much better)... But hey, what the heck!

$MyString = 'This i-s a test SmOke_N_2006-03Mar-31-Fri-00Hr-10Min and o-nly a test'
MsgBox(0, 'Test', I_Dont_Know_What_To_Call_This_Function($MyString))

Func I_Dont_Know_What_To_Call_This_Function($s_String)
    Local $s_Mid[3]
    Local $i_RightArray = 1
    
    If StringInStr($s_String, '-') And (UBound(StringSplit($s_String, '-')) - 1) >= 6 Then
        Local $a_Split_String = StringSplit($s_String, '-')
        
        If (UBound(StringSplit($s_String, '-')) - 1) >= 7 Then
            For $i_Count = 1 To UBound($a_Split_String) - 1
                If StringInStr($a_Split_String[$i_Count], '_') Then
                    $i_RightArray = $i_Count
                    ExitLoop
                EndIf
            Next
        EndIf
        
        For $i_Split = 1 To UBound($a_Split_String) - 1
            If $i_Split == 1 Then
                For $i_Mid1 = StringLen($a_Split_String[$i_RightArray]) To 1 Step - 1
                    $s_Mid[1] = StringMid($a_Split_String[$i_RightArray], $i_Mid1, 1)
                    If $s_Mid[1] = Chr(32) Then
                        $s_Mid[1] = StringRight($a_Split_String[$i_RightArray], StringLen($a_Split_String[$i_RightArray]) - ($i_Mid1))
                        ExitLoop
                    EndIf
                Next
            EndIf
            If $i_Split == 6 Then
                For $i_Mid6 = 1 To StringLen($a_Split_String[$i_RightArray + 5])
                    $s_Mid[2] = StringMid($a_Split_String[$i_RightArray + 5], $i_Mid6, 1)
                    If $s_Mid[2] = Chr(32) Then
                        $s_Mid[2] = StringLeft($a_Split_String[$i_RightArray + 5], ($i_Mid6 - 1))
                        ExitLoop
                    EndIf
                Next
            EndIf
        Next
        
        Return $s_Mid[1] & '-' & $a_Split_String[$i_RightArray + 1] & '-' & $a_Split_String[$i_RightArray + 2] & '-' & _ 
        $a_Split_String[$i_RightArray + 3] & '-' & $a_Split_String[$i_RightArray + 4] & '-' & $s_Mid[2]
    EndIf
EndFunc

Edit:

Forgot to (dot) an "i" and (cross) a "t"

Edited by SmOke_N

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

what is the output you would like ?

H'mmn, Obviously I haven't explained myself well.

Pattern: c...c_nnnn-nnaaa-nn-aaa-nnaa-nnaaa

where c = any alpha-numeric character

------ ... = an unknown number of characters

------- a = any alpha character

------- n = any numeric digit

Examples of desired results...

SmOke_N_2006-03Mar-31-Fri-00Hr-10Min

regan_2006-03Mar-31-Fri-01Hr-23Min

The pattern and two example above are examples of desirable folder name results. The only parts I will know in advance are:

c...c_20nn-nnaaa-nn-aaa-nnHr-nnMin

where c = any alpha-numeric character

------ ... = an unknown number of characters

------- a = any alpha character

------- n = any numeric digit

I have tried dir /a:d *_2???-?????-??-???-??Hr-??Min with and without quotes to get a directory listing with no result. I'm left with getting a general listing of ALL dirs. I was thinking I could then use StrinRegExp to find all the dirs that fit the pattern above.

If I've made a bad assumption, please point it out.

Gene


[font="Verdana"]Thanks for the response.Gene[/font]Yes, I know the punctuation is not right...

Share this post


Link to post
Share on other sites

H'mmn, Obviously I haven't explained myself well.

Pattern: c...c_nnnn-nnaaa-nn-aaa-nnaa-nnaaa

where c = any alpha-numeric character

------ ... = an unknown number of characters

------- a = any alpha character

------- n = any numeric digit

Examples of desired results...

SmOke_N_2006-03Mar-31-Fri-00Hr-10Min

regan_2006-03Mar-31-Fri-01Hr-23Min

The pattern and two example above are examples of desirable folder name results. The only parts I will know in advance are:

c...c_20nn-nnaaa-nn-aaa-nnHr-nnMin

where c = any alpha-numeric character

------ ... = an unknown number of characters

------- a = any alpha character

------- n = any numeric digit

I have tried dir /a:d *_2???-?????-??-???-??Hr-??Min with and without quotes to get a directory listing with no result. I'm left with getting a general listing of ALL dirs. I was thinking I could then use StrinRegExp to find all the dirs that fit the pattern above.

If I've made a bad assumption, please point it out.

Gene

i'm going to try my hand at this one. could you post a couple more of your actual sub directory names, so that i can create a true test

1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

Well worse case, did you test the function I made to see if it will suit your needs if needed?


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Well worse case, did you test the function I made to see if it will suit your needs if needed?

you should use EncodeIt on your examples. to make them look more scary

1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

you should use EncodeIt on your examples. to make them look more scary

Should have saved it for Holloween? :)

In all seriousness... I tested it on a few things, it was quite efficient.


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Lazycat was on the right track. I think you should look at that post again. Test each folder against that pattern to determine if it matches.

Edited by Stumpii

“Give a man a script; you have helped him for today. Teach a man to script; and you will not have to hear him whine for help.”AutoIt4UE - Custom AutoIt toolbar and wordfile for UltraEdit/UEStudio users.AutoIt Graphical Debugger - A graphical debugger for AutoIt.SimMetrics COM Wrapper - Calculate string similarity.

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

Lazycat was on the right track. I think you should look at that post again. Test each folder against that pattern to determine if it matches.

yeah that's the way that i did it. i made 2 subs with the examples, in c:\test\ then i ran a "dir /s /ad c:\test\ > c:\test\subs.txt"

to generate a file for the dir/s /ad, then imported that to an array, and checked each line via regex, outputting only the filename portion of the valid directories. here's the portion that read in the list of subs, and wrote the output file

#include<file.au3>
$ouput = FileOpen("C:\test\output.txt",1)
Dim $values
_FileReadToArray("c:\test\subs.txt",$values)
For $x = 1 to $values[0]
    If StringLen($values[$x]) > 2 Then
    $aresult = StringRegExp($values[$x],'([0-9]{4}-[0-9]{2}\D{3}-[0-9]{2}-\D{3}-[0-9]{2}Hr-[0-9]{2}Min)')
    If $aresult And Not StringInStr($values[$x],"Directory of") Then FileWriteLine($ouput,StringRight($values[$x],StringLen($values[$x])-39))
    EndIf
Next

***edit***

also, although i think using the dir/s /ad output is the most efficient, you could reduce file I/O by just doing a FileFindFirstFile ... FileFindNextFile and evaluating the ones with the D attribute. I wouldn't, but you could.

Edited by cameronsdad

1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

yeah that's the way that i did it. i made 2 subs with the examples, in c:\test\ then i ran a "dir /s /ad c:\test\ > c:\test\subs.txt"

to generate a file for the dir/s /ad, then imported that to an array, and checked each line via regex, outputting only the filename portion of the valid directories. here's the portion that read in the list of subs, and wrote the output file

#include<file.au3>
$ouput = FileOpen("C:\test\output.txt",1)
Dim $values
_FileReadToArray("c:\test\subs.txt",$values)
For $x = 1 to $values[0]
    If StringLen($values[$x]) > 2 Then
    $aresult = StringRegExp($values[$x],'([0-9]{4}-[0-9]{2}\D{3}-[0-9]{2}-\D{3}-[0-9]{2}Hr-[0-9]{2}Min)')
    If $aresult And Not StringInStr($values[$x],"Directory of") Then FileWriteLine($ouput,StringRight($values[$x],StringLen($values[$x])-39))
    EndIf
Next

***edit***

also, although i think using the dir/s /ad output is the most efficient, you could reduce file I/O by just doing a FileFindFirstFile ... FileFindNextFile and evaluating the ones with the D attribute. I wouldn't, but you could.

There is no difference if your going to go through line by line with StringRegExp() and the function I wrote. That seems a waiste of it's abilities IMHO.

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

There is no difference if your going to go through line by line with StringRegExp() and the function I wrote. That seems a waiste of it's abilities IMHO.

few things

1 ) Waste, not waiste :)

2 ) Mine is a tad shorter...

3 ) although i could use a regular expression to return an array of hits on the pattern, the pattern is not the full file name, which is what he needs. so going line by line is the way to go. so how was your weekend? i got crazy drunk last night and now i'm at work. not hung over so much as still a little drunk.


1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

i'm going to try my hand at this one. could you post a couple more of your actual sub directory names, so that i can create a true test

gts_2006-04Apr-02-Sun-14Hr-57Min

gts_2006-04Apr-01-Sat-00Hr-55Min

gts_2006-03Mar-23-Thu-23Hr-22Min

cb_2006-03Mar-31-Fri-23Hr-15Min

dawn_2006-04Apr-03-Mon-00Hr-55Min

michelle_2006-03Mar-30-Thu-00Hr-15Min

The characters before the first underscore are the user id. This is on Win9x & Win2k PCs, other unrelated folders appear among them too. I have to leave alone any folders not in this naming scheme and keep the 14 newest folders for any user id in this naming scheme. I just want help with the stringregexp I just gave to other info in case it might help.

Thanks for your response and help.

Gene


[font="Verdana"]Thanks for the response.Gene[/font]Yes, I know the punctuation is not right...

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

gts_2006-04Apr-02-Sun-14Hr-57Min

gts_2006-04Apr-01-Sat-00Hr-55Min

gts_2006-03Mar-23-Thu-23Hr-22Min

cb_2006-03Mar-31-Fri-23Hr-15Min

dawn_2006-04Apr-03-Mon-00Hr-55Min

michelle_2006-03Mar-30-Thu-00Hr-15Min

The characters before the first underscore are the user id. This is on Win9x & Win2k PCs, other unrelated folders appear among them too. I have to leave alone any folders not in this naming scheme and keep the 14 newest folders for any user id in this naming scheme. I just want help with the stringregexp I just gave to other info in case it might help.

Thanks for your response and help.

Gene

This should match the basic pattern (not tested):

(?i)(.*?)_(\d\d\d\d)\-(\d\d\D\D\D)\-(\d\d)\-(\D\D\D)\-(\d\d\D\D)\-(\d\d\D\D\D)

I would loop the directory matching to this pattern and if the match returned true (by checking @Extended, and using a regex parameter of 3), rebuild the directory as $results[1] & "_" & $results[2] & "-" & $results[3] & "-" & $results[4] etc.

Each paren with the exception of the first case insensitive directive would be an array element. You would need to rebuild the directory with the underscore and - seperators. If @extended returns true, test the results array for 7 elements (plus the [0] count) to determine that the match is exact.

While I am sure there is probably a more elegant way to do it, this should work and be reliable.

[edit]

After re-reading your post, you could also separate the elements containing date fields like -(\d\d\D\D\D), or time fields into 2 groups -(\d\d)(\D\D\D) to make it easier to parse for determining the most recent folders. Adjust your array element count accordingly.

[/edit]

Edited by billmez

Share this post


Link to post
Share on other sites

;Custom UDF for Gene
;Written by neogia
;Requires: ArrayToDisplayString.au3 (attached to post)

#include <ArrayToDisplayString.au3>
#include <GUIConstants.au3>

$dir = "C:\testing"; Change to the directory of your choice

FileChangeDir($dir)
$handle = FileFindFirstFile($dir & "\*.*")
$check = FileFindNextFile($handle)
Local $results[1][15];[n][0] = user [n][1-14] = 14 most recent folders
$results[0][0] = 0;count
While @error == 0
    If FileGetAttrib($dir & "\" & $check) == "D" Then
        $user = StringRegExp($check, "(\a+?)_\d{4}-\d{2}\a{3}-\d{2}-\a{3}-\d{2}\a{2}-\d{2}\a{3}", 1)
        If @extended == 1 Then
            $notFound = 1
            For $i = 1 To $results[0][0]
                If $results[$i][0] == $user[0] Then
                    For $j = 1 To 13
                        If $results[$i][14 - $j] <> "" Then
                            $results[$i][14 - $j + 1] = $results[$i][14 - $j]
                        EndIf
                    Next
                    $results[$i][1] = $check
                    $notFound = 0
                EndIf
            Next
            If $notFound == 1 Then
                ReDim $results[$results[0][0] + 2][15]
                $results[0][0] += 1
                $results[$results[0][0]][0] = $user[0]
                $results[$results[0][0]][1] = $check
            EndIf
        EndIf
    EndIf
    $check = FileFindNextFile($handle)
WEnd

;Creates a nice output for results
GUICreate("Results", 370, 370)
$edit = GUICtrlCreateEdit("", 10, 10, 350, 350)
GUICtrlSetData($edit, _ArrayToDisplayString($results))
GUISetState()

;Message Loop
$msg = GUIGetMsg()
While $msg <> $GUI_EVENT_CLOSE
    Sleep(10)
    $msg = GUIGetMsg()
WEnd

Just got back from a weekend of snowboarding in Colorado, and was delighted to see this post, and thought I'd spend some of my free time whipping something up. It sorts through $dir, looking for directories that match your requirements (used LazyCat's very elegant StringRegEx pattern; nice work!) It also utilizes a queue technique so only the most recent 14 folders are matched. I hope you like it. Note: requires ArrayToDisplayString.au3 (attached) only to display results nicely, not needed for core function to work.

ArrayToDisplayString.au3


[u]My UDFs[/u]Coroutine Multithreading UDF LibraryStringRegExp GuideRandom EncryptorArrayToDisplayString"The Brain, expecting disaster, fails to find the obvious solution." -- neogia

Share this post


Link to post
Share on other sites

gts_2006-04Apr-02-Sun-14Hr-57Min

gts_2006-04Apr-01-Sat-00Hr-55Min

gts_2006-03Mar-23-Thu-23Hr-22Min

cb_2006-03Mar-31-Fri-23Hr-15Min

dawn_2006-04Apr-03-Mon-00Hr-55Min

michelle_2006-03Mar-30-Thu-00Hr-15Min

The characters before the first underscore are the user id. This is on Win9x & Win2k PCs, other unrelated folders appear among them too. I have to leave alone any folders not in this naming scheme and keep the 14 newest folders for any user id in this naming scheme. I just want help with the stringregexp I just gave to other info in case it might help.

Thanks for your response and help.

Gene

these also work with the solution i provided in earlier post. no problem, always glad to help

1100111 00001011101111 00011101101111 00010111100100 00001111110100 00110111110010 00101101111001 0011100i didn't make up this form of encryption, but i like it.credit to the lvl 6 challenge on arcanum.co.nz

Share this post


Link to post
Share on other sites

these also work with the solution i provided in earlier post. no problem, always glad to help

Thanks to everyone who has responded! Circumstances are requiring me to work on something else at the moment. As soon as I am free to, I will try out each of the solutions. I will probably use the fastest one that works as expected (1 or 2 of them were said to be untested). Hopefully as I work through the code of each one I will come to grips with StrigRegExp.

Gene :)


[font="Verdana"]Thanks for the response.Gene[/font]Yes, I know the punctuation is not right...

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  
Followers 0