New version runs the same test in 13 seconds. Method: the loop first finds the filename position in the slimmed dat and starts a simplified regex from that position.
The new version replaces your lines 66 to 105 with this
posi = 1
needle = <description>(.*)</description>
Loop, Parse, ThumbnailFileList, `n, `r
{
if A_LoopField =
continue
SplitPath, A_LoopField,,,,filename ;### trim the file extension from the name
posi := InStr(datcontents, """" filename """",false,posi) ;filename position in datcontents
RegExMatch(datcontents,"U)" needle, datname, posi) ;start regex from filename position
if !datname1
continue
newname := char(datname1)
FileCopy, %artsource%\%filename%.png, %destinationfolder%\%newname%.png, 1
}
;change forbidden chars
char(x) {
x := StrReplace(x, "'", "'")
x := StrReplace(x, "&", "_")
x := StrReplace(x, "&", "_")
x := StrReplace(x, "\", "_")
x := StrReplace(x, "/", "_")
x := StrReplace(x, "?", "_")
x := StrReplace(x, ":", "_")
x := StrReplace(x, "<", "_")
x := StrReplace(x, ">", "_")
x := StrReplace(x, "*", "_")
x := StrReplace(x, "|", "_")
return x
}
This new version also saves more images to destinationfolder (13507 images compared to 12629 images). Not sure why there is a difference.