Jump to content
Sign in to follow this  
hawkair

Insert Line Numbers in text with Stringregexpreplace

Recommended Posts

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

 

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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 by hawkair
Added Word of caution

Share this post


Link to post
Share on other sites

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 by ViciousXUSMC

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
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

 

Share this post


Link to post
Share on other sites

:blink:

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.

Share this post


Link to post
Share on other sites

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

 

Share this post


Link to post
Share on other sites

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 by jguinch

Share this post


Link to post
Share on other sites
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. 

Share this post


Link to post
Share on other sites

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

 

Share this post


Link to post
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
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By ni3dprint
      Hi folks, 
      Thank you so much in advance for your help!  I've been using AUTOIT for manipulating gcode.  So far I've just worked through the excellent help examples and although I'm sure the resulting code is clumsy it has functioned  
      However now I'm trying to improve and advance things and I've stumbled across REGEX.. and I'm a bit stuck.  What I would like to be able to do is to 'move'/'transform' the gcode in a file and re-write it to a new file.  I only need to move it in one direction(X).  At the heart of this I need a script to extract all the X values and then ADD or SUBTRACT an adjustment factor to transform and rewrite the code accordingly.
      So far using an example script and an example input -
      Func Test2()
      Local $iMove = -4
          Local $sInput = '"G1 X45.036 Y6.934 F7800.000 G1 Z0.600 F7800.000 G1 F900 G1 X48.036 Y1.076 E0.58925"'
          Local $sOutput = StringRegExpReplace($sInput, '(?<=[X])\d+.\d+', '\0')
          Display($sInput, $sOutput)
      EndFunc   ;==>Test2
      This identifies the correct values i.e 45.036 and 48.036 but is there a way to dyamically adjust them before they are replaced, by for example a factor of -4 ($iMove above).  So far I can't seem to do math on the '\0' value i.e '\0'+ -4 ?
      Many thanks for your time and expertise!
       
    • By jmp
      i am trying to get number from string using this code :
      #include <IE.au3> $oIE = _IEAttach ("Edu.corner") Local $aName = "Student name & Code:", $iaName = "0" Local $oTds = _IETagNameGetCollection($oIE, "td") For $oTd In $oTds If $oTd.InnerText = $aName Then $iaName = $oTd.NextElementSibling.InnerText $iGet = StringRegExpReplace($iaName, "\D", "") EndIf Next MsgBox(0, "", $iGet) it was get number like 52503058
      But, I want to get only student code 5250. (Different student have different code, sometime its 3 digits, Sometime 4)

       
    • By SkysLastChance
      I am trying to figure out why my mouse move does not end up in the same spot as the test version
      I am on the struggle bus. (Both Examples below)
      #include <IE.au3> Local $xWidth = 2 Local $xHeight = 2 Local $vOperator = '/' Local $oIE = _IE_Example("form") Local $oForm = _IEFormGetObjByName($oIE, "ExampleForm") Local $oTextArea = _IEGetObjByName($oForm, "imageExample") Local $iScreenX = _IEPropertyGet($oTextArea, "screenx") Local $iScreenY = _IEPropertyGet($oTextArea, "screeny") Local $iWidth = _IEPropertyGet($oTextArea, "width") Local $iHeight = _IEPropertyGet($oTextArea, "height") Local $iMousespeed = 20 MouseMove($iScreenX + $iWidth / 2, $iScreenY + $iHeight / 2, $iMousespeed) ;Test Example ;;MouseMove(Execute(($iScreenX + $iWidth) & $vOperator & $xWidth), Execute(($iScreenY + $iHeight) & $vOperator & $xHeight), 25) ;My Example  
    • By jmp
      I am adding labour charge to total paid amount using : 
      #include <IE.au3> #include <Array.au3> $oIE = _IEAttach ("Shop") $oTable = _IETableGetCollection ($oIE, 1) $aTableData3 = _IETableWriteToArray ($oTable) Local $sitem1 = $aTableData3[5][1] Local $sitem2 = $aTableData3[5][2] Local $lcharge = "10" ;add manualy using inputbox, becuase not generating online Local $atotPric = "Payable Total Price " Local $oTds = _IETagNameGetCollection($oIE, "td") For $oTd In $oTds If $oTd.Innertext = $atotPric Then $iatotPric = $oTd.NextElementSibling.innertext MsgBox (0, "2", $iatotPric) EndIf Next $irCtotal = StringFormat("%.2f", $sitem1 + $sitem2 + $lcharge) $crTotp = StringReplace(_IEBodyReadHTML($oIE), $iatotPric, $irCtotal) _IEBodyWriteHTML ($oIE, $crTotp) But, It was also changing Total price, I want to change only Payable Total Price.

    • By nacerbaaziz
      hello sirs
      i've some questions about StringRegExpReplace i hope you can help me
       
      i tried to make a function that give me the host of the url and other give me the url with out host
      for example i've this link
      https://www.example.com/vb/result.php
      i need the first give me the
      example.com
      and the other give me 
      /vb/result.php
      i find that
      $s_source = "https://www.google.com/vb/index.php" Local $s_Host = StringRegExpReplace($s_Source, '.*://(.*?)/.*', '\1') Local $s_Page = StringRegExpReplace($s_source, '.*://.*?(/.*)', '\1') msgBox(64, $s_Host, $s_Page)  
      but i found some problems i need your help to correct it
      first: when i get the host if the url has www i want to remove it
      second: if the url with out host did not have other things 
      i need the result to be ""
      e.g
      https://www.example.com
      the first i want it
      example.com
      and the second i want it to be ""
      i hope that you can help me
      thanks in advance
×
×
  • Create New...