hawkair Posted August 15, 2016 Posted August 15, 2016 Hi I am trying to insert line numbers in to a string with this script Func _MyInc () Static Local $i = 0 $i += 1 Return $i EndFunc Exit _InsertLines() Func _InsertLines() $String = "A" & @CRLF & "B" & @CRLF & "C" & @CRLF & "D" $NewString = Execute("'" & StringRegExpReplace($String,"[\r\n]*", "' & _MyInc () & '\1" ) & "'") MsgBox (0, "", $NewString) EndFunc but I get this: 1A23B45C67D8 I never really could master how Execute works here and I always get some working example and make substitutions. But this is the closest i could get...
SadBunny Posted August 15, 2016 Posted August 15, 2016 Here's an interesting Stack Overflow thread about using an increasing counter in Regex: http://stackoverflow.com/questions/12941362/is-it-possible-to-increment-numbers-using-regex-substitution But I would personally go for something simpler like this: #include <StringConstants.au3> #include <Array.au3> $LINE_INCREMENT = 10 $string = "A" & @CRLF & "B" & @CRLF & "C" & @CRLF & "D" $aLines = StringSplit($string, @CRLF, $STR_ENTIRESPLIT + $STR_NOCOUNT) For $iLine = 0 to UBound($aLines) - 1 $aLines[$iLine] = (($iLine + 1) * $LINE_INCREMENT) & " " & $aLines[$iLine] Next $newString = _ArrayToString($aLines, @CRLF) MsgBox(0, 0, $newString) Unless the texts get really really big, then I'd probably just use a Powershell oneliner. Roses are FF0000, violets are 0000FF... All my base are belong to you.
hawkair Posted August 15, 2016 Author Posted August 15, 2016 (edited) Thanks SadBunny I actually wanted to avoid stringsplits and For Loops I believe I got it correct now (after many trials of quote placing...) I also include a formatted version for line numbers Func _MyInc () Static Local $i = 0 $i += 1 Return $i EndFunc Func _InsertLines() $String = "A" & @CRLF & "B" & @CRLF & "C" & @CRLF & "D" & @CRLF & "A" & @CRLF & "B" & @CRLF & "C" & @CRLF & "D" & @CRLF & "A" & @CRLF & "B" & @CRLF & "C" & @CRLF & "D" $NewString = StringTrimLeft (Execute("'" & StringRegExpReplace($String,"(?|\A|[\r\n]+)", @CRLF & "' & _MyInc () & '." ) & "'"), 2) MsgBox (0, "", $NewString) $NewString = StringTrimLeft (Execute("'" & StringRegExpReplace($String,"(?|\A|[\r\n]+)", @CRLF & "' & StringFormat (""%3d"", _MyInc ()) & '." ) & "'"), 2) MsgBox (0, "", $NewString) EndFunc _InsertLines() A word of caution though. There are problems (I just verified it) with this solution if $String contains single quotes ('). Execute gets confused. So either search and replace ' with something unique like say "[singlequote]" or go with Sadbunnys solution Edited August 15, 2016 by hawkair Added Word of caution
ViciousXUSMC Posted August 15, 2016 Posted August 15, 2016 (edited) I was trying to be creative and keep this just inside the StringRegExp() to do everything, but looks like even though I have a function to increment the line numbers that the replacement part of StringRegExp only calls the function one time instead of each time it does a replacement. Global $iCount = 0 $String = "A" & @CRLF & "B" & @CRLF & "C" & @CRLF & "D" $NewString = StringRegExpReplace($String, "([^\r\n])", FuncCounter($iCount) & " " & "$1") MsgBox(0, "", $NewString) Func FuncCounter(ByRef $iCount) $iCount = $iCount +1 Return $iCount EndFunc I have a lingering feeling that there is still a way to do it in a similar manner in where the RegExp itself returns the number of replacements it has made and that could be the increment factor. Edited August 15, 2016 by ViciousXUSMC
jchd Posted August 15, 2016 Posted August 15, 2016 That can't be done in a single PCRE regexp, I mean without external code. It can be done in Perl for instance (see (?p{...}) in the PCRE pattern documentation), but this implies Perl interpolating code, which is somehow cheating, similar to the concatenation with Execute. To avoid single quotes breaking things, wrap the string part with StringReplace($s, "'", "''"). Also \R is efficient to match a line termination. 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 hereRegExp tutorial: enough to get startedPCRE 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)
Malkey Posted August 15, 2016 Posted August 15, 2016 6 hours ago, jchd said: ,,,, concatenation with Execute .... An example of the ' concatenation with Execute' as mentioned above. Local $String = "A1" & @CRLF & "B2" & @CRLF & "C3" & @CRLF & "D4" ;& @CRLF Local $NewString = '"1: " & "' & StringRegExpReplace($String, "(\R)", '$1" & _Counter() & ": ') & '"' ConsoleWrite($NewString & @LF) MsgBox(0, "Results", Execute($NewString)) Func _Counter() Local Static $iCount = 1 $iCount += 1 Return $iCount EndFunc ;==>_Counter SadBunny 1
SadBunny Posted August 16, 2016 Posted August 16, 2016 Wow... How does that work? How is _Counter executed more than once? Roses are FF0000, violets are 0000FF... All my base are belong to you.
mikell Posted August 16, 2016 Posted August 16, 2016 ... and here is the jguinch's way applied to Malkey's example Local $String = "A1" & @CRLF & "B2" & @CRLF & "C3" & @CRLF & "D4" ;& @CRLF Local $i = 1 Local $NewString = '$i & ": " & "' & StringRegExpReplace($String, "(\R)", _ '$1" & Assign("i", Eval("i")+1)*Eval("i") & ": ') & '"' ConsoleWrite($NewString & @LF) MsgBox(0, "Results", Execute($NewString))
jguinch Posted August 16, 2016 Posted August 16, 2016 (edited) I was preparing the reply mine is almost the same : Local $sString = "A1" & @CRLF & "B2" & @CRLF & "C3" & @CRLF & "D4" $sOutput = Execute ( "'" & StringRegExpReplace( StringReplace($sString, "'", "''") , "(?m)^", "' & (Assign(""iReplace"", Eval(""iReplace"") + 1) * 0 + Eval(""iReplace"")) & ' - ") & "'" ) MsgBox(0, "", $sOutput) Edited August 16, 2016 by jguinch Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF
SadBunny Posted August 16, 2016 Posted August 16, 2016 Damn, them's some pretty nifty pieces of code! Roses are FF0000, violets are 0000FF... All my base are belong to you.
ViciousXUSMC Posted August 16, 2016 Posted August 16, 2016 12 hours ago, Malkey said: An example of the ' concatenation with Execute' as mentioned above. Local $String = "A1" & @CRLF & "B2" & @CRLF & "C3" & @CRLF & "D4" ;& @CRLF Local $NewString = '"1: " & "' & StringRegExpReplace($String, "(\R)", '$1" & _Counter() & ": ') & '"' ConsoleWrite($NewString & @LF) MsgBox(0, "Results", Execute($NewString)) Func _Counter() Local Static $iCount = 1 $iCount += 1 Return $iCount EndFunc ;==>_Counter This seems the similar of the above. How does this work exactly? I notice just adding Execute() to my code does not work so its not like magic, definitely more to it.
Mat Posted August 16, 2016 Posted August 16, 2016 Another method that doesn't rely on execute trickery, using a function I wrote for using callbacks with regex. Local $sInput = "This is a test." & @CRLF & "Line 2" & @CRLF & "Line 3" & @CRLF & "Line 4" & @CRLF & "Line 5" & @CRLF & "Line 6" Local $sTest = "1: " & StringRegExpReplaceCallback($sInput, "\R", _Callback) MsgBox(0, "Test", $sTest) Func _Callback($aRes) Local Static $iCount = 1 $iCount += 1 Return @CRLF & $iCount & ": " EndFunc Func StringRegExpReplaceCallback($sString, $sPattern, $sFunc, $iLimit = 0) Local $iOffset = 1, $iDone = 0, $iMatchOffset While True $aRes = StringRegExp($sString, $sPattern, 2, $iOffset) If @error Then ExitLoop $sRet = Call($sFunc, $aRes) If @error Then Return SetError(@error, $iDone, $sString) $iOffset = StringInStr($sString, $aRes[0], 1, 1, $iOffset) $sString = StringLeft($sString, $iOffset - 1) & $sRet & StringMid($sString, $iOffset + StringLen($aRes[0])) $iOffset += StringLen($sRet) $iDone += 1 If $iDone = $iLimit Then ExitLoop WEnd Return SetExtended($iDone, $sString) EndFunc ;==>StringRegExpReplaceCallback AutoIt Project Listing
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