Jump to content

Array search with wildcards, maybe even regex?


TagK
 Share

Recommended Posts

I have this function i wrote. where I search in an array for "trash" then using the output from _ArraySearch, I delete the bit with the trash.

It is impossible for me to add all variations of this filename to my function.

Basically this is what I got for now :

func _magic()
local $filelist = _FileListToArray($oldPath) ; read filenames from the path to array, the oldpath variable is from another function, its just a good old standard filepath.

Local $telle
local $Trash[2]
$Trash[0] = "*.db"
$Trash[1] = "*.sfv"


while 1
$telle = 0 ; set to 0 to make sure it starts at the beginning of the array.

$findTrash = _ArraySearch($filelist,$Trash[$telle])

if $findTrash > 0 Then
_ArrayDelete($filelist,$findTrash)
Else
ExitLoop
EndIf
$telle = $telle + 1
WEnd

EndFunc

Is there any way I can easily get to the filenames i want to delete, in a simple manner, Like not converting the entire array to a string and using regex on the string and then back to an array using stringsplit?

Thanks for reading this

Programming Novice, interested in c++ (i know maybe 1%) AutoIT and many more.Projects : Anime renamer

Link to comment
Share on other sites

I'm not sure if you wish to keep or delete all files ending with the file extensions you mention. Finding all files with those extensions would only involve examining the last 3 or 4 characters from each array element. This does not really need RegExp. You can loop through the array backwards (starting at the end) and delete any file name with those extensions. You only need to use For To Step -1 and StringRight functions. Of course you can use RegExp too, but I don't see much advantage in this case.

If on the other hand you need to use wildcards, then you will need to use RegExp. All possible matches need to be accounted for, otherwise it's very difficult to give advice.

Edited by czardas
Link to comment
Share on other sites

If it were me, I would create an array just for the trash. Here's how I would do it.

#include <array.au3>
#include <file.au3>

$fList = _FileListToArray(@ScriptDir)
Dim $trashList[1]
$j = 1
For $i = 1 to $fList[0] Step 1
    If StringRight($fList[$i], 3) = "sfv" or StringRight($fList[$i], 2) = "db" Then
        $trashList[$j - 1] = $fList[$i]
        ReDim $trashList[$j + 1]
        $j += 1
    EndIf
Next
_ArrayDisplay($trashList)

The only thing is the last element in the array will always be blank. You could trim it, but then again, it might not be important to do so.

Edited by abberration
Link to comment
Share on other sites

If it were me, I would create an array just for the trash.

I agree. Here's how I would do it.

#Include <File.au3>
#Include <Array.au3>

Global $iErrors = 0

Dim $array1 = _GetTrash("db")
Dim $array2 = _GetTrash("sfv")

Switch $iErrors
    Case 0
        $array1[0] += $array2[0] ; Add to get total number of matches.
        _ArrayConcatenate($array1, $array2, 1)
    Case 1
        If $array1 = 0 Then $array1 = $array2
EndSwitch
$array2 = 0 ; $array2 is no longer needed.

If $iErrors < 2 Then _ArrayDisplay($array1)

Func _GetTrash($extension, $Dir = @ScriptDir)
    Local $aTemp = _FileListToArray($Dir, "*." & $extension, 1)
    If @error Then $iErrors += 1
    Return $aTemp
EndFunc
Link to comment
Share on other sites

Thanks guys, I am however not certain to why I would want to make a 2nd array with the trash. When I simply want to 100% discard it from the system.

Basically : Read directory -> Remove trash -> use array for stuff.

not Read Directory -> copy trash to other array leaving the first array intact -> .?

Then again I could misunderstand what you guys are trying to say.

So basically, I need a way to remove it from the array, and to do that. I kinda need either to handle the array in another way or some way to get the placement of the trash in the array to feed it into the _ArrayDelete function.

Programming Novice, interested in c++ (i know maybe 1%) AutoIT and many more.Projects : Anime renamer

Link to comment
Share on other sites

I thought trash needed to be deleted. Creating an array of files to send to the trash. That's what it sounded like to me. >_<

The following method may be adequate: If could take a long time if you have a lot of files to test. There are faster alternatives, but it gets more complicated and requires information about the files you want to keep. Using _ArrayDelete tends to slow things down somewhat. It's better to exclude the trash from the start - not adding these files to the array ever, if that is possible.

#Include <File.au3>
#Include <Array.au3>

$array = _FileListToArray(@ScriptDir, "*.*", 1)

For $i = $array[0] To 1 Step -1
    If StringRight($array[$i] ,4) = ".sfv" Or StringRight($array[$i] ,3) = ".db" Then
        _ArrayDelete($array, $i)
        $array[0] -= 1
    EndIf
Next

_ArrayDisplay($array)
Edited by czardas
Link to comment
Share on other sites

I thought trash needed to be deleted. Creating an array of files to send to the trash. That's what it sounded like to me. >_<

The following method may be adequate: If could take a long time if you have a lot of files to test. There are faster alternatives, but it gets more complicated and requires information about the files you want to keep. Using _ArrayDelete tends to slow things down somewhat. It's better to exclude the trash from the start - not adding these files to the array ever, if that is possible.

#Include <File.au3>
#Include <Array.au3>

$array = _FileListToArray(@ScriptDir, "*.*", 1)

For $i = $array[0] To 1 Step -1
If StringRight($array[$i] ,4) = ".sfv" Or StringRight($array[$i] ,3) = ".db" Then
_ArrayDelete($array, $i)
$array[0] -= 1
EndIf
Next

_ArrayDisplay($array)

Excellent, why did I not think of this. I already have a module that decides upon the file ending of the files in the folder, I can pipe that into the array to decide what files to load, and as such render the entire delete proccess moot.

I love programming :D

Programming Novice, interested in c++ (i know maybe 1%) AutoIT and many more.Projects : Anime renamer

Link to comment
Share on other sites

Or, don't load the files into your array in the first place.

There are multiple versions of a recursive _FileListToArray() that allow for excluding files using a parameter with wildcards such as:

" *.db;*.sfv;*.log;*"

This is a small, fast one I often use:

Melba has a larger version that has subfolder depth and sort parameters that is popular.

You'll find a dozen versions with the exclusion option if you search the Examples forum...

Edit: Most of these also allow multiple "include" strings with wildcards allowed. So, between the include and exclude parameters, you can pretty much tailor your list to what you want. The functions all also have a parameter to disable recursive folder searching (typically the default) when it is not required.

Edited by Spiff59
Link to comment
Share on other sites

I'd be interested to know how you might do this. Spiff59 has answered that already. :)

Sure I'll show you.

First run this :

Func _getFilepath() ; procures the path of the file you need to change the name of.
            $path = FileOpenDialog("Select file", "x:", "Video (*.mp4;*.mkv;*.avi;*.ogm;*.wmv)", 1 + 4) ; openfile dialoge window, allows multiple file selections, but must have at least one.
            GUICtrlSetData($filePath, $path) ; writes the original filename and path into a label
EndFunc ;==>_getFilepath

then run

Func _getfileinfo() ; get the filename and the path of the file, and then the ending of the file
               $path = GUICtrlRead($filePath) ; read the filepath you just gave it
               $split = StringSplit($path, "", 2) ; read the entire path into an array, sepparated by the  delimiter.
               $telle = UBound($split) ; figure out how "big" the array is, then set that number to the $telle variable
               $telle = $telle - 1 ; subtract one, because of reasons and stuff
               $oldName = _ArrayToString($split, "", $telle) ; convert the array part with the information i need.
               $fileEnding = StringRegExp($path,'.ogm|.avi|.mkv|.wmv',2) ; looking for the various file endings it supports for now, can be expanded later
               $fileEnding = _ArrayToString($fileEnding,"") ; Store the file type in a standard variable
       If $telle >= 2 Then ; figure out how to best split the path
                   $oldPath = _ArrayToString($split, "", 0, $telle - 1) ; get the path based on earlier split variable
       Else
                 $oldPath = $split[0]
       EndIf
              $oldPath = $oldPath & "" ; add a  to the end of the path, for example "C:path" to "C:path" - this is to make the file rename later possible
              GUICtrlSetState($change, $GUI_ENABLE) ; enable the next button
EndFunc ;==>_getfileinfo

Then this

Func _magic() ; call the array $filelist to get the name of ALL the files in the directory.
Local $telle
local $test
Local $skriv
Local $mappe
local $filelist = _FileListToArray($oldPath, "*" & $fileEnding ) ; read filenames from the path to array
         GUICtrlSetData($FileListBox,"") ; clean out the listbox ready for a new set of entries
       $derp = _ArrayToString($filelist,", ",1)
       $episodetall = StringRegExp($derp,'s-s(d{1,})|_(d{1,})_?[',3)
       _ArrayDelete($filelist, 0)
       $mappe = UBound($filelist) -1
       for $telle = 0 to $mappe
       GUICtrlSetData($FileListBox,$filelist[$telle]) ; write the array to the listbox, for the filenames
Next

       GUICtrlSetState($PreviewName, $GUI_ENABLE) ; enable the button
EndFunc

Thats about it I think,

Programming Novice, interested in c++ (i know maybe 1%) AutoIT and many more.Projects : Anime renamer

Link to comment
Share on other sites

Thanks! I didn't study your code in depth, but there are plenty of ways to create your array. Whether your method works or not, I would still look at Spiff59's link. Sometimes you just need a fresh perspective. Good luck with it. :)

Aye, my code works perfectly now. Seems instant for me. I will have a loop at Spiff59's link to see if its any different.

In a totally different note, I have found that the place where I read stuff into my other arrays have changed stuff. So I need to create a new function that figures out why and what and where.

Programming Novice, interested in c++ (i know maybe 1%) AutoIT and many more.Projects : Anime renamer

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...