How to replace a number range with same rang just adding an offset. ie find a 3 digit number between say 133 to 183, add 64 and replace the original number.



  • HI.

    I feel there is a simple way to do this but so far I cant see the way. I wonder if the reg expression people can assist?

    In an original table of numbers (other stuff included like colons, letters etc) from 133 to 183 for instance, I then copy this to a new location and want to increment the original value range by adding an offset like 64.

    I would select the new range, use find and replace to take the original range numbers 133 to 183 then add 64 and replace the number in the range with the new number.

    I am just not sure of the terminology to do this.

    \d means a number, just need a push in the right direction next.

    Thanks again.



  • Hi, minsikau

    I don’t think than you can easily perform a S/R, with computation, with the present BOOST regex engine, used by Notepad++ :-(

    But this goal could be reached, if you would install the N++ Python plugin of Dave Brotherstone

    Just refer to that link below, for some information :

    https://sourceforge.net/p/npppythonscript/discussion/1199074/thread/8d2ed95a/?limit=25#628b

    I’m not completely sure, but be aware that, in this script, the command editor.pyreplace....., should be replaced with the command editor.rereplace, with the last 1.0.8.0 version of the N++ Python plugin

    No doubt, that, very soon, Claudia Franck, ( a definitive Python fan and master ! ) will propose you a “ready-to-use” script, to achieve your goals !

    Best Regards,

    guy038



  • Hello @minsikau and guy038

    yes, python can do it as long as I do the correct regexes ;-)

    This one line should do the trick.
    Once you have installed python script plugin you can run this in
    the console (Plugins->Python Script->Show Console)
    or create a new Script and run it afterwards.

    editor.rereplace('[1][3][3-9]|[1][4-7][0-9]|[1][8][0-3]', lambda m: str(int(m.group(0)) + 60))
    

    To get the number range I did the following alternations

    either the number starts with 1 followed by 3 and follows by digits 3-9

    [1][3][3-9]
    

    or number starts with 1 followed by digits 4-7 and follows by digits 0-9

    [1][4-7][0-9]
    

    or number starts with 1 followed by 8 and follows by digits 0-3

    [1][8][0-3]
    

    If there is a better/nicer/quicker/usefuller (?) regex, maybe someone (guy038 ;-)
    can enlight me?

    Cheers
    Claudia



  • Hello, minsikau and Claudia,

    minsikau, if you’re exactly searching for a three digits number, from 133 to 183, a possible regex could be :

    \b1(3[3-9]|[4-7]\d|8[0-3])\b
    

    Notes :

    • The \b assertion, which represents the limit between a word character and a non-word character or the opposite, ensure that a right number, as 157, will NOT be matched if it’s glued in a bigger number as, for instance, in the number 3415798 !

    • Then, the first digit 1 is needed, in every case, and for the “ten” and “unit” digits, we have to choose between 3 possibilities :

      • The ten digit 3, followed with the unit digit between 3 and 9
      • The ten digit between 4 and 7, followed by any digit (\d )
      • The ten digit 8, followed with the unit digit between 0 and 3
    • And, finally, a second \b assertion

    Remark :

    Strictly speaking, for characters displayed by the usual Courrier New font, the regex syntax \d represents a single digit, in one of the four lines below :

    0123456789      Digit Zero to Nine                           [\x{0030}-\x{0039}]         or  [0-9]
    ¹²³             Superscript One, Two and Three               [\x{00b9}\x{00b2}\x{00b3}]  or  [¹²³]
    ٠١٢٣٤٥٦٧٨٩    Arabic-Indic digits Zero to Nine             [\x{0660}-\x{0669}]
    ۰۱۲۳۴۵۶۷۸۹    Eastern Arabic-Indic digits Zero to Nine     [\x{06f0}-\x{06f9}]
    

    Happily, most of the time, these details, don’t matter at all !


    So, to conclude, the Python script could be :

    editor.rereplace('\b1(3[3-9]|[4-7]\d|8[0-3])\b', lambda m: str(int(m.group(0)) + 64))
    

    Cheers,

    guy038



  • Thanks so much for the tips.
    You GUYS are awesome. I am a bloke but love you all :) Pun intended especially for GUY038 which i have just read.

    Seems like some very useful information here.

    I added the Python.script plugin and when opening the console it shows an “unknown exception” error. I changed configuration for loading at “startup” and NPP++ opens fine, only when I try to open the python script console.
    Hmm now it opened without error! (too early in the morning, here its 5am!). Now i can try the script.

    The actual sequence i am working on is

    :REG_137:137:S
    :REG_138:138:U
    :REG_139:139:U
    :REG_140:140:U

    and to replace all ocurrences of the number 137, 138,139,140 with a new set of numbers that happen to be currently 64 (may not be this exactly in future) higher. in other words this is a cpu register translation file. I am probably going to be copying in a batch of these, and just wanting to update a selection to a different memory block range.
    I hope the extra info helps narrow down the requirements.

    My steps so far.
    I select just the number range in NPP++, then in the python script console paste the suggested command and press run. the command then appears in the console area with a >>>> beginning but doesnt do anything on the selected text. Scratched head. What am i doing wrong.



  • @guy038 said:

    \b1(3[3-9]|[4-7]\d|8[0-3])\b

    I use this in my find box and it is finding numbers from 133 to 183 but only the last number in the row. Too much to learn!
    REG_137:137:S I need to find both 137 and 137 then replace them with the new number.
    my example number could be from 10-99 or 100-999 and need to learn what makes the number range. Happy to work on a block of 100, even that would be super useful.
    again thanks.

    Also how to makeit work on the selected range. I can then manually select the column range then apply the script?



  • Hello @minsikau,

    I don’t think you did something wrong, it looks like the installation
    of the plugin didn’t succeed. The unexpected error is a strong indication.
    Do you mind installing the python script plugin again?
    But this time use the MSI package from here.
    Just install, no need to remove it first it will overwrite existing files.

    The code needs to be modified, the word boundaries must be escaped.

    editor.rereplace('\\b1(3[3-9]|[4-7]\d|8[0-3])\\b', lambda m: str(int(m.group(0)) + 64))
    

    But as guy038 already mentioned, it does only replace numbers which aren’t bind to other chars.

    :REG_137:137:S
    :REG_138:138:U
    :REG_139:139:U
    :REG_140:140:U

    The first 137 … is bind to REG_

    If you can be sure that no numbers like 51374 appear and needs to be replaced, remove the \\b
    from the code and it should replace all instances in the editor not only the selected ones.
    If you want to work on selection than you must use one particular way to select the numbers
    because it would result in different selections otherwise.

    Cheers
    Claudia



  • Thanks Claudia.
    I have downloaded the MSI and installed that which seems to run fine, no complaints this time. In the console it now shows ok and works on my selection.
    However it only works on the last number in the row.
    ie :REG_133_1:197:B:0 The 133 is original, the 197 is the newly updated number. Even if the first 133 is in the selection in column mode it doesnt touch it obviously considers the whole line before doing its magic. Maybe its binding to “_” ?

    I am happy to just do a small block at a time as anything is much faster than looking between different documents to do it manually. So i prefer the work on selection method.

    Really appreciate the guidance here. So many power things to use if only I could learn them all. I can see now the python script plugin opens up many new manipulations.



  • Hello minsikau,

    If you want to operate on selection a one liner isn’t possible anymore.
    Use Plguins->Python Script->New Script and copy the following script into it.
    Save it with a meaningful name.

    Important, the selection made must be either a single line or made in column mode,
    this is by pressing ALT key and then selecting the text.

    import re
    
    def replaceIt(word):
        return re.sub('1(3[3-9]|[4-7]\d|8[0-3])', lambda m: str(int(m.group(0)) + 64),word)
        
    for i in range(editor.getSelections()):
        start = editor.getSelectionNStart(i)
        end = editor.getSelectionNEnd(i)
        word = editor.getTextRange(start,end)
        if len(word) > 0 and (word.isspace() != True):
            editor.setTarget(start, end)
            editor.replaceTarget('{0}'.format(replaceIt(word)))
    

    So, selcet text and run script from menu.

    If there are any questions let me know.

    Cheers
    Claudia



  • thanks Claudia.
    I have moved past those files so cant test currently.
    In future I will be back to the pesky lists again so will check then.
    Really appreciate the guidance.

    MInsik


Log in to reply