Replace text with incremented counter



  • I ended up using TextPad it would be nice if Notepad ++ could also do this

    I ended up using TextPad



  • @Rupert-Russell

    The best way to do it in Notepad++ is with the Pythonscript plugin.



  • @Alan-Kilborn Hi Alan, Is there a good tutorial on how to add the plugin, I don’t know how to add it.



  • @Rupert-Russell

    best way, afaik, is to use the Plugins Admin from plugins menu I guess.



  • @Rupert-Russell

    BTW, it’s NOT an automatic thing.
    Meaning that if you just install the plugin you’ll be able to do what you want in a nice way.
    Installing the plugin only means that you have scripting functionality (yay!).

    There are some examples of doing it with a script on this forum in previous posts.

    In the coming days I’ll put together a sample that makes it work like Textpad (on a ReplaceAll basis). At this point I’m thinking it won’t have an awesome UI but maybe @Ekopalypse has some techniques that could help out with that.



  • There are some examples of doing it with a script on this forum in previous posts.

    Not to forget the help function in the python script console

    >>> help(editor.rereplace)
    Help on method rereplace:
    
    rereplace(...) method of Npp.Editor instance
        rereplace( (Editor)arg1, (object)searchRegex, (object)replace) -> None :
            Regular expression search and replace. Replaces 'searchRegex' with 'replace'.  ^ and $ by default match the starts and end of the document.  Use additional flags (re.MULTILINE) to treat ^ and $ per line.
            The 'replace' parameter can be a python function, that recieves an object similar to a re.Match object.
            So you can have a function like
               def myIncrement(m):
                   return int(m.group(1)) + 1
            
            And call rereplace('([0-9]+)', myIncrement) and it will increment all the integers.
    ...
    




  • @Ekopalypse Thanks for your input. I have limited experience with Python. In my use case, I am appending an incrementing counter at the start of every line that is preceded with a pair of carriage returns.

    This numbers each question in the Aiken file. see: http://rupert.id.au/aiken/

    Kind regards,
    Rupert.



  • Hi @Alan-Kilborn thanks that would be useful. I have installed Python script into Notepad ++ and I will a play with

    Something more like this, Thanks for the link.
    https://community.notepad-plus-plus.org/topic/15318/replace-text-with-incremented-counter

    count = -1

    def calculate(m):
    global count
    count += 1
    return ‘<TAG>’ + str(count) + ‘<TAG>’

    editor.rereplace(’<TAG>([0-9]+)<TAG>’, calculate);



  • @Rupert-Russell said in Replace text with incremented counter:

    This numbers each question in the Aiken file. see: http://rupert.id.au/aiken/

    Hi. As a test I decided to see what’s involved in doing this via a regular expression. As the others stated, it would be better using a scripting/programming language however that then involves additional learning, something that might not produce a result quickly.

    It is certainly possible (at least in my limited testing). Using the examples I gathered from your link I ran up 10 questions. Essentially the steps would be:

    1. Have each question and multiple answers appear on 1 line, with the question first.
      2.Insert an incrementing number at the start of the line and if necessary move it to the correct position.
    2. Change the lines back to the original format with question first. The next few lines would be the multiple answers, followed by a blank line.

    Now although I have stated 3 steps, in fact each one has a few steps within, however the option is there should you wish to pursue that idea.

    Good luck
    Terry



  • Hello @rupert-russell, @alan-kilborn, @terry-r and All,

    Oh, I first thought, as many others, that this goal, needing calculations, was beyond the scope of regular expressions !

    But, reading @terry-r’s post, I realized that, indeed, a regex solution is possible, in that specific case ;-)) And I already guessed how @terry-r would achieve it !

    I, myself found out a solution, which uses, successively, a 1st regex S/R, then the Column Editor feature and, then, a 2nd regex S/R

    Let’s wait a bit for the OP’s answer. Then, we could compare our solutions, ah ah !

    Best Regards,

    guy038



  • @Alan-Kilborn said in Replace text with incremented counter:

    In the coming days I’ll put together a sample that makes it work like Textpad (on a ReplaceAll basis). At this point I’m thinking it won’t have an awesome UI but maybe @Ekopalypse has some techniques that could help out with that.

    I saw some activity in this thread (someone upvoted some of my postings–nice–LOL), so I just thought I’d add a comment saying that I’m still working on the script I mentioned.
    It has suffered from my usual problem: feature creep :-) :-(
    Stay tuned…



  • Hi, @rupert-russell, @alan-kilborn, @terry-r and All,

    OK, Alan, So here is my regex solution, ( already written ! )

    Assuming that :

    • Each possible answer begins with an uppercase letter, immediately followed by a dot and a space characters

    • The correct letter is preceded by the string ANSWER, in uppercase, immediately followed by a colon and a space characters

    Let’s start with this initial text data, below, where I, intentionally, added additional line-breaks, in a random order, and removed some others, in order to simulate a general format :

    This a first test!
    
    A. This is
    B. a test
    
    
    C. to build
    D. the regex
    ANSWER: A
    
    This a second test!
    
    
    
    A. This is
    
    B. a test
    
    C. to build
    D. the regex
    ANSWER: B
    This a third test!
    A. This is
    B. a test
    
    C. to build
    
    
    D. the regex
    
    ANSWER: C
    
    • Run this first regex S/R :

      • SEARCH (?-i)\R+(?=\u\.\x20|ANSWER:)|(\R)+

      • REPLACE ?1\1:\x20

    You should obtain the following text, where all stuff of each test is moved in a single line :

    This a first test! A. This is B. a test C. to build D. the regex ANSWER: A
    This a second test! A. This is B. a test C. to build D. the regex ANSWER: B
    This a third test! A. This is B. a test C. to build D. the regex ANSWER: C
    

    Now, let’s suppose that we have a 12-lines list ( instead of 3-lines ) :

    This a first test! A. This is B. a test C. to build D. the regex ANSWER: A
    This a second test! A. This is B. a test C. to build D. the regex ANSWER: B
    This a third test! A. This is B. a test C. to build D. the regex ANSWER: C
    This a fourth test! A. This is B. a test C. to build D. the regex ANSWER: D
    This a fifth test! A. This is B. a test C. to build D. the regex ANSWER: A
    This a sixth test! A. This is B. a test C. to build D. the regex ANSWER: B
    This a seventh test! A. This is B. a test C. to build D. the regex ANSWER: C
    This a eighth test! A. This is B. a test C. to build D. the regex ANSWER: D
    This a ninth test! A. This is B. a test C. to build D. the regex ANSWER: A
    This a tenth test! A. This is B. a test C. to build D. the regex ANSWER: B
    This a eleventh test! A. This is B. a test C. to build D. the regex ANSWER: C
    This a twelfth test! A. This is B. a test C. to build D. the regex ANSWER: D
    
    • Move the caret at the very beginning of the first line

    • Select the option Edit > Column Editor

      • Choose the Number to Insert main option

      • Type in the value 1 in each field

      • Do not tick the Leading zeros box ( IMPORTANT )

      • Verify that the format is Dec

      • Click on the OK button

    You’ll get :

    1 This a first test! A. This is B. a test C. to build D. the regex ANSWER: A
    2 This a second test! A. This is B. a test C. to build D. the regex ANSWER: B
    3 This a third test! A. This is B. a test C. to build D. the regex ANSWER: C
    4 This a fourth test! A. This is B. a test C. to build D. the regex ANSWER: D
    5 This a fifth test! A. This is B. a test C. to build D. the regex ANSWER: A
    6 This a sixth test! A. This is B. a test C. to build D. the regex ANSWER: B
    7 This a seventh test! A. This is B. a test C. to build D. the regex ANSWER: C
    8 This a eighth test! A. This is B. a test C. to build D. the regex ANSWER: D
    9 This a ninth test! A. This is B. a test C. to build D. the regex ANSWER: A
    10This a tenth test! A. This is B. a test C. to build D. the regex ANSWER: B
    11This a eleventh test! A. This is B. a test C. to build D. the regex ANSWER: C
    12This a twelfth test! A. This is B. a test C. to build D. the regex ANSWER: D
    13
    
    • Get rid of the empty line 13, at end of this list, if you wish to

    • Now, run this second and final regex S/R :

      • SEARCH ^\d+(\x20)?|\x20(\u\.\x20|ANSWER:)

      • REPLACE \r\n?2\2:$0?1:\x20

    Here is your expected numbered list of 12 tests. Voila !

    1 This a first test
    A. This is
    B. a test
    C. to build
    D. the regex
    
    2 This a second test
    A. This is
    B. a test
    C. to build
    D. the regex
    
    3 This a third test
    A. This is
    B. a test
    C. to build
    D. the regex
    
    4 This a fourth test
    A. This is
    B. a test
    C. to build
    D. the regex
    
    5 This a fifth test
    A. This is
    B. a test
    C. to build
    D. the regex
    
    6 This a sixth test
    A. This is
    B. a test
    C. to build
    D. the regex
    
    7 This a seventh test
    A. This is
    B. a test
    C. to build
    D. the regex
    
    8 This a eighth test
    A. This is
    B. a test
    C. to build
    D. the regex
    
    9 This a nineth test
    A. This is
    B. a test
    C. to build
    D. the regex
    
    10 This a tenth test
    A. This is
    B. a test
    C. to build
    D. the regex
    
    11 This a eleventh test
    A. This is
    B. a test
    C. to build
    D. the regex
    
    12 This a twelfth test
    A. This is
    B. a test
    C. to build
    D. the regex
    

    Best Regards,

    guy038



  • @guy038

    Hmmm, this may be a case of missing the forest while seeing the trees.

    The script will be a general-purpose solution which mostly follows the OP’s desire, meaning, at replace-time, a special syntax can be present in the replace string which will allow count-based replacement.

    Here’s the syntax that I’m thinking:

    foo \i(103,-4,'03') bar

    This would cause the first replacement to be foo 103 bar, the second replacement to be foo 099 bar, the third is foo 096 bar, etc.

    I deviate a bit from what the OP exactly wanted, with an optional argument:

    Note that my 3rd argument to the \i syntax – which is '03' above, is a format specifier for Python’s string formatting routine. Thus for my specific example, it causes zero-padding to a field-width of three, as one can observe in my 099 and 096 output samples.

    Another example might be foo \i(103,-4,'#x') bar and here are some successive replacements:

    foo 0x67 bar
    foo 0x63 bar
    foo 0x5f bar
    foo 0x5b bar
    

    …and so on…

    There doesn’t appear to be a great link to the Python format strings, but here’s one that will sort of lead there: https://docs.python.org/3.4/library/string.html#formatstrings

    By the way, @guy038, I use this regex in code to parse the \i syntax: \\i(?:\((-?\d+)(?:,(-?\d+))?(?:,'(?-s)(.*?)')?\))?. I thought you might enjoy seeing/knowing that. :-)




Log in to reply