Jump to content

StringRegExp file extension


Go to solution Solved by mikell,

Recommended Posts

In the first expression, (.*) is greedy so the regex will grab in the backreference all chars until the last dot found

In the 2nd, read : "a dot, and 0 or more non-dot chars (lazy), up to the end"

This laziness means that the concerned dot must be the last one found before the end

Edited by mikell
Link to comment
Share on other sites

this is a function i have always problems with

 

Don't worry, you are not the only one.  I'll join the queue.

Your original solution is slower than the regex solutions.

 

But my solution without regex is the fastest. :thumbsup: 

 

Here the script:

$sFilename = 'test.txt.exe.bat'
$iLoopcount = 200000

$iTimer = TimerInit()
For $i = 1 To $iLoopcount
    $sNewFilename = StringReverse($sFilename)
    $sNewFilename = StringRight($sNewFilename, StringLen($sNewFilename) - StringInStr($sNewFilename, '.'))
    $sNewFilename = StringReverse($sNewFilename)
Next
$iTime = TimerDiff($iTimer)
ConsoleWrite("Using StringReverse" & @CRLF)
ConsoleWrite($sNewFilename & "  " & $iTime & @CRLF & @CRLF)

$iTimer = TimerInit()
For $i = 1 To $iLoopcount
    $sNewFilename = StringRegExpReplace($sFilename, '(.*)\..*', "$1")
Next
$iTime = TimerDiff($iTimer)
ConsoleWrite("Using StringRegExpReplace Pattern 1" & @CRLF)
ConsoleWrite($sNewFilename & "  " & $iTime & @CRLF & @CRLF)

$iTimer = TimerInit()
For $i = 1 To $iLoopcount
    $sNewFilename = StringRegExpReplace($sFilename, '\.[^.]*?$', "")
Next
$iTime = TimerDiff($iTimer)
ConsoleWrite("Using StringRegExpReplace Pattern 2" & @CRLF)
ConsoleWrite($sNewFilename & "  " & $iTime & @CRLF & @CRLF)

$iTimer = TimerInit()
For $i = 1 To $iLoopcount
    $sNewFilename = StringLeft($sFilename, StringInStr($sFilename, ".", 0, -1) - 1)
Next
$iTime = TimerDiff($iTimer)
ConsoleWrite("Using StringLeft" & @CRLF)
ConsoleWrite($sNewFilename & "  " & $iTime & @CRLF & @CRLF)
And here the result:

Using StringReverse
test.txt.exe  7111.68181138629

Using StringRegExpReplace Pattern 1
test.txt.exe  1545.96028171841

Using StringRegExpReplace Pattern 2
test.txt.exe  1211.85814138758

Using StringLeft
test.txt.exe  1022.85245008591
Conclusion:

Regex is not always the best solution.  :graduated:

Edited by Exit

App: Au3toCmd              UDF: _SingleScript()                             

Link to comment
Share on other sites

In the latest beta it should be.

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

>"C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /beta /ErrorStdOut /in "C:UsersADMIN010Documentsaa.au3" /UserParams   
+>04:35:09 Starting AutoIt3Wrapper v.14.801.2025.0 SciTE v.3.4.4.0   Keyboard:00000409  OS:WIN_7/Service Pack 1  CPU:X64 OS:X64    Environment(Language:0409)
+>         SciTEDir => C:Program Files (x86)AutoIt3SciTE   UserDir => C:UsersADMIN010AppDataLocalAutoIt v3SciTEAutoIt3Wrapper   SCITE_USERHOME => C:UsersADMIN010AppDataLocalAutoIt v3SciTE
>Running AU3Check (3.3.13.19)  from:C:Program Files (x86)AutoIt3Beta  input:C:UsersADMIN010Documentsaa.au3
+>04:35:09 AU3Check ended.rc:0
>Running:(3.3.13.19):C:\Program Files (x86)\AutoIt3\Beta\autoit3.exe "C:UsersADMIN010Documentsaa.au3"   
--> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop
Using StringReverse
test.txt.exe  5916.72078644539

Using StringRegExpReplace Pattern 1
test.txt.exe  987.68195765385

Using StringRegExpReplace Pattern 2
test.txt.exe  880.383014436886

Using StringLeft
test.txt.exe  924.562870379159

+>04:35:18 AutoIt3.exe ended.rc:0
+>04:35:18 AutoIt3Wrapper Finished.
>Exit code: 0    Time: 9.334

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

Getting rid of the unnecessary lazy qualifier in  '.[^.]*?$', and adding a possessive qualifier to stop any unnecessary backtracking,we have:-

$filename = StringRegExpReplace($filename, '\.[^.]++$', "")

Or, '.[^.]*+$' also works.

When running:AutoIt Beta version 3.3.13.19, this StringRegExpReplace pattern is the fastest when added to Exit's example of post #6 and run on my (OS:WIN_7/Service Pack 1  CPU:X64 OS:X64) system.

Link to comment
Share on other sites

Right. Both possessive qualifier and atomic groups deserve a more common use.

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

In the latest beta it should be.

Yes, in the latest beta, the REGEX with pattern2 had the better value.

Now, I tweaked my solution to be case insensitive ...., and this solution made the race. :thumbsup:

 

Script:

$sF = 'test.txt.exe.bat'
$iLc = 200000
ConsoleWrite("AutoIt Version: " & @AutoItVersion & @CRLF)
$iTime = TimerInit()
For $i = 1 To $iLc
    $sN = StringReverse($sF)
    $sN = StringRight($sN, StringLen($sN) - StringInStr($sN, '.'))
    $sN = StringReverse($sN)
Next
$iTime = TimerDiff($iTime)
ConsoleWrite($sN & "  " & $iTime & "  Using StringReverse" & @CRLF)

$iTime = TimerInit()
For $i = 1 To $iLc
    $sN = StringRegExpReplace($sF, '(.*)\..*', "$1")
Next
$iTime = TimerDiff($iTime)
ConsoleWrite($sN & "  " & $iTime & "  Using StringRegExpReplace Pattern 1" & @CRLF)

$iTime = TimerInit()
For $i = 1 To $iLc
    $sN = StringRegExpReplace($sF, '\.[^.]*?$', "")
Next
$iTime = TimerDiff($iTime)
ConsoleWrite($sN & "  " & $iTime & "  Using StringRegExpReplace Pattern 2" & @CRLF)

$iTime = TimerInit()
For $i = 1 To $iLc
    $sN = StringRegExpReplace($sF, '\.[^.]++$', "")
Next
$iTime = TimerDiff($iTime)
ConsoleWrite($sN & "  " & $iTime & "  Using StringRegExpReplace Pattern 3" & @CRLF)

$iTime = TimerInit()
For $i = 1 To $iLc
    $sN = StringLeft($sF, StringInStr($sF, ".", 0, -1) - 1)
Next
$iTime = TimerDiff($iTime)
ConsoleWrite($sN & "  " & $iTime & "  Using StringLeft" & @CRLF)

$iTime = TimerInit()
For $i = 1 To $iLc
    $sN = StringLeft($sF, StringInStr($sF, ".", 1, -1) - 1)
Next
$iTime = TimerDiff($iTime)
ConsoleWrite($sN & "  " & $iTime & "  Using StringInString casesensitive " & @CRLF)

Output:

AutoIt Version: 3.3.12.0
test.txt.exe  7500.66292707802  Using StringReverse
test.txt.exe  1646.92385042465  Using StringRegExpReplace Pattern 1
test.txt.exe  1288.35341365462  Using StringRegExpReplace Pattern 2
test.txt.exe  1253.17301843785  Using StringRegExpReplace Pattern 3
test.txt.exe  1039.94437720284  Using StringLeft
test.txt.exe  907.057500783347  Using StringInString casesensitive 

AutoIt Version: 3.3.13.19
test.txt.exe  6964.1790005509  Using StringReverse
test.txt.exe  1128.0553115061  Using StringRegExpReplace Pattern 1
test.txt.exe  1011.7741747203  Using StringRegExpReplace Pattern 2
test.txt.exe  932.270028610106  Using StringRegExpReplace Pattern 3
test.txt.exe  1066.81534910678  Using StringLeft
test.txt.exe  921.09672755274  Using StringInString casesensitive

But I'm sure, a REGEX guru will show a even faster solution. :ILA:>

Edited by Exit

App: Au3toCmd              UDF: _SingleScript()                             

Link to comment
Share on other sites

 

When running:AutoIt Beta version 3.3.13.19, this StringRegExpReplace pattern is the fastest when added to Exit's example of post #6 and run on my (OS:WIN_7/Service Pack 1  CPU:X64 OS:X64) system.

I incorporated your new solution in my post #11

Again, REGEX is not the fastest.

But the race not finished. Awaiting new pattern. :thumbsup:

App: Au3toCmd              UDF: _SingleScript()                             

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...