Mat Posted October 12, 2009 Posted October 12, 2009 (edited) A few new functions that are very useful, and very simple if you know your RegEx. Most of these i've accumulated over the weeks from questions in h+s, and other projects I've been doing. These are also pretty good examples of how to use RegExp, particularly the \Q and \E tags which I feel are seriously under used. The other thing that should be used more are the {} tags for repetition a fixed amount of times, they've been used in there too. expandcollapse popupFunc _StringInStrCount ($sString, $sFind, $bCaseSense = False) Local $sCase = "(?i)" If $bCaseSense = True Then $sCase = "" Return UBound (StringRegExp ($sString, $sCase & "(\Q" & $sFind & "\E)", 3)) EndFunc ; ==> _StringInStrCount Func _StringSplitByLine ($sString, $bCountBlank = False) Local $sChar = "+" If $bCountBlank = True Then $sChar = "*" Return StringRegExp ($sString, "(." & $sChar & ")(?:\n)?", 3) EndFunc ; ==> _StringSplitByLine Func _StringAddLine ($sString, $iLine, $sLine, $bCountBlank = False) Local $sChar = "+" If $bCountBlank = True Then $sChar = "*" If Not IsInt ($iLine) Then Return SetError (1, 0, "") Return StringRegExpReplace ($sString, "((." & $sChar & "(\n)){" & $iLine & "})(?s)(." & $sChar & ")", "\1" & $sLine & "\3\4") EndFunc ; ==> _StringAddLine Func _StringGetLine ($sString, $iLine, $bCountBlank = False) Local $sChar = "+" If $bCountBlank = True Then $sChar = "*" If Not IsInt ($iLine) Then Return SetError (1, 0, "") Return StringRegExpReplace ($sString, "((." & $sChar & "\n){" & $iLine & "})(." & $sChar & "\n)((." & $sChar & "\n?)+)", "\2") EndFunc ; ==> _StringGetLine Func _StringRemoveLine ($sString, $iLine, $bCountBlank = False) Local $sChar = "+" If $bCountBlank = True Then $sChar = "*" Return StringRegExpReplace ($sString, "((." & $sChar & "\n){" & $iLine - 1 & "})(." & $sChar & "\n?)(." & $sChar & "\n*)", "\1\4") EndFunc ; ==> _StringRemoveLine Func _StringGetAfter ($sString, $sChar, $bFirst = True, $bCaseSense = False) Local $sGreed = "", $sCase = "(?i)" If $bFirst = False Then $sGreed = "(?u)" If $bCaseSense = True Then $sCase = "" Return StringRegExpReplace ($sString, $sCase & $sGreed & "(?s).*?\Q" & $sChar & "\E(.*)", "\1") EndFunc ; ==> _StringGetAfter Func _StringGetBefore ($sString, $sChar, $bFirst = True, $bCaseSense = False) Local $sGreed = "", $sCase = "(?i)" If $bFirst = False Then $sGreed = "(?u)" If $bCaseSense = True Then $sCase = "" Return StringRegExpReplace ($sString, $sGreed & "(?s)(.*?)\Q" & $sChar & "\E(.*)\z", "\1") EndFunc ; ==> _StringGetBefore Func _StringGetFirstLine ($sString) Return StringRegExpReplace ($sString, "\n.*", "") EndFunc ; ==> _StringGetFirstLine Func _StringGetLastLine ($sString) Return StringRegExpReplace ($sString, ".*\n", "") EndFunc ; ==> _StringGetLastLine Mat Edited October 13, 2009 by Mat AutoIt Project Listing
Authenticity Posted October 12, 2009 Posted October 12, 2009 Nice functions. You can do a benchmark to see which approach is faster. For example, StringReplace is sometimes a faster and better alternative: Just a simple benchmark: Local $a = "ABA" & @CRLF & "CBC" & @CRLF & "DBD" Local $b For $i = 1 To 6 $a &= $a Next Local $init = 0 $init = TimerInit() For $i = 1 To 1000 $b = UBound (StringRegExp ($a, "(\QB\E)", 3)) Next ConsoleWrite($b & @TAB & TimerDiff($init) & @CRLF) $init = TimerInit() For $i = 1 To 1000 StringReplace($a, "B", "", 0, 1) $b = @extended Next ConsoleWrite($b & @TAB & TimerDiff($init) & @CRLF) There is no difference in benching for case-(in)sensitivity.
Mat Posted October 12, 2009 Author Posted October 12, 2009 (edited) It could be interesting to see which methods favour longer + shorter strings though... Thats a very interesting set of results there though: 192 1258.41133440144 192 106.548457974407 I tried it on a considerably larger string (FileRead (WinApi.au3)), and StringReplace was considerably faster... From all the tests i've done, StringReplace has been faster actually ah well, its all that array handling, if I can find a way around that then I might be able to tighten the gap a bit. I should probably be using StringRegExp and reading that extended value... Yet testing on 6 winapi.au3's: Local $a = FileRead (StringTrimRight (@AutoitEXE, 11) & "include\WinApi.au3") Local $b For $i = 1 To 6 $a &= $a Next Local $init = 0 $init = TimerInit() StringRegExpReplace ($a, "(\Q_WinAPI_SetWindowLong\E)", "") $b = @Extended $ret = $b & @TAB & TimerDiff($init) & @CRLF $init = TimerInit() StringReplace($a, "_WinAPI_SetWindowLong", "", 0, 1) $b = @extended $ret &= $b & @TAB & TimerDiff($init) MsgBox (0, "Results!", $ret) Mat Edit: And into 4 digits at last!! I'm not going to post now just to keep on that magic 1000 Edited October 12, 2009 by Mat AutoIt Project Listing
Authenticity Posted October 12, 2009 Posted October 12, 2009 Just a tiny thing. $a &= $a is not x times $a but 2^x times what $a had at first.
Zedna Posted October 12, 2009 Posted October 12, 2009 Nice functions, especially: _StringGetLine() _StringRemoveLine() What about a new one: _StringAddLine()? Resources UDF ResourcesEx UDF AutoIt Forum Search
Mat Posted October 12, 2009 Author Posted October 12, 2009 a few more than just six times then... ah well, minor detail and has very little relevence to the actual fact that stringReplace is considerably faster... Mat AutoIt Project Listing
Mat Posted October 12, 2009 Author Posted October 12, 2009 (edited) No problem Zedna: Func _StringAddLine ($sString, $iLine, $sLine, $bCountBlank = False) Local $sChar = "+" If $bCountBlank = True Then $sChar = "*" If Not IsInt ($iLine) Then Return SetError (1, 0, "") Return StringRegExpReplace ($sString, "((." & $sChar & "(\n)){" & $iLine & "})(?s)(." & $sChar & ")", "\1" & $sLine & "\3\4") EndFunc ; ==> _StringAddLine Mat Edit: Now uses current line break character. Edited October 13, 2009 by Mat AutoIt Project Listing
Zedna Posted October 12, 2009 Posted October 12, 2009 No problem Zedna:Thanks Mat. I'm total RegExp amateur. Resources UDF ResourcesEx UDF AutoIt Forum Search
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now