[regex] Notepad++ incrementally replace

Lets say I want to have a 10 rows of data but I want a value to increment for each row or piece of data. How do I increment that value?

For example....If I have these rows, is there a regex way of replacing the id values to increment?

<row id="1" />
<row id="1" />
<row id="1" />
<row id="1" />
<row id="1" />

--- Here is what I would like it to look like... (if the first row's id goes up one thats ok)

<row id="1" />
<row id="2" />
<row id="3" />
<row id="4" />
<row id="5" />

This question is related to regex notepad++ sequential

The answer is



Solutions suggested above will work only if data is aligned..
See solution in the link using PythonScript Notepad++ plugin, It Works great!

stackoverflow Find/Replace but Increment Value


(Posting in case someone might have a use of it).

I was looking for a solution for a problem a bit more sophisticated than OP - replacing EVERY occurrence of something with the number by same thing with incremented number

E.g. Replacing something like this:

<row id="1" />
<row id="2" />
<row id="1" />
<row id="3" />
<row id="1" />

By this:

<row id="2" />
<row id="3" />
<row id="2" />
<row id="4" />
<row id="2" />

Couldnt find the solution online so I wrote my own script in groovy (a bit ugly but does the job):

 /**
 * <p> Finds words that matches template and increases them by 1.
 * '_' in word template represents number.
 *
 * <p> E.g. if template equals 'Row="_"', then:
 * ALL Row=0 will be replaced by Row="1"
 * All Row=1 will be replaced by Row="2"
 * <p> Warning - your find template might not work properly if _ is the last character of it
 * etc.
 * <p> Requirments:
 * - Original text does not contain tepmlate string
 * - Only numbers in non-disrupted sequence are incremented and replaced
 * (i.e. from example below, if Row=4 exists in original text, but Row=3 not, than Row=4 will NOT be 
 * replaced by Row=5)
 */
def replace_inc(String text, int startingIndex, String findTemplate) {
    assert findTemplate.contains('_') : 'search template needs to contain "_" placeholder'
    assert !(findTemplate.replaceFirst('_','').contains('_')) : 'only one "_" placeholder is allowed'
    assert !text.contains('_____') : 'input text should not contain "______" (5 underscores)'
    while (true) {
        findString = findTemplate.replace("_",(startingIndex).toString())
        if (!text.contains(findString)) break;
        replaceString = findTemplate.replace("_", "_____"+(++startingIndex).toString())
        text = text.replaceAll(findString, replaceString)
    }
    return text.replaceAll("_____","") // get rid of '_____' character
}

// input
findTemplate = 'Row="_"'
path = /C:\TEMP\working_copy.txt/
startingIndex = 0

// do stuff
f = new File(path)
outText = replace_inc(f.text,startingIndex,findTemplate)
println "Results \n: " + outText
f.withWriter { out -> out.println outText }
println "Results written to $f"

i had the same problem with more than 250 lines and here is how i did it:

for example :

<row id="1" />
<row id="1" />
<row id="1" />
<row id="1" />
<row id="1" />

you put the cursor just after the "1" and you click on alt + shift and start descending with down arrow until your reach the bottom line now you see a group of selections click on erase to erase the number 1 on each line simultaneously and go to Edit -> Column Editor and select Number to Insert then put 1 in initial number field and 1 in incremented by field and check zero numbers and click ok

Congratulations you did it :)


Since there are limited real answers I'll share this workaround. For really simple cases like your example you do it backwards...

From this

1
2
3
4
5

Replace \r\n with " />\r\n<row id=" and you'll get 90% of the way there

1" />
<row id="2" />
<row id="3" />
<row id="4" />
<row id="5

Or is a similar fashion you can hack about data with excel/spreadsheet. Just split your original data into columns and manipulate values as you require.

|   <row id="   |   1   |   " />    |
|   <row id="   |   1   |   " />    |
|   <row id="   |   1   |   " />    |
|   <row id="   |   1   |   " />    |
|   <row id="   |   1   |   " />    |

Obvious stuff but it may help someone doing the odd one-off hack job to save a few key strokes.


http://docs.notepad-plus-plus.org/index.php/Inserting_Variable_Text

Notepad++ comes equipped with a Edit -> Column "Alt+C" Editor which can work on a rectangular selection in two different ways: Coledit.png inserting some fixed text on every line including and following the current line, at the column of the insertion point (aka caret). Initially selected text is left untouched. As the picture illustrates, a linear series of numbers can be inserted in the same manner. The starting value and increment are to be provided. Left padding with zeroes is an option, and the number may be entered in base 2, 8, 10 or 16 - this is how the computed values will be displayed too, padding being based on the largest.


You can do it using Powershell through regex and foreach loop, if you store your values in file input.txt:

$initialNum=1; $increment=1; $tmp = Get-Content input.txt | foreach {  $n = [regex]::match($_,'id="(\d+)"').groups[1
].value; if ($n) {$_ -replace "$n", ([int32]$initialNum+$increment); $increment=$increment+1;} else {$_}; }

After that you can store $tmp in file using $tmp > result.txt. This doesn't need data to be in columns.


I was looking for the same feature today but couldn't do this in Notepad++. However, we have TextPad to our rescue. It worked for me.

In TextPad's replace dialog, turn on regex; then you could try replacing

<row id="1"/>

by

<row id="\i"/>

Have a look at this link for further amazing replace features of TextPad - http://sublimetext.userecho.com/topic/106519-generate-a-sequence-of-numbers-increment-replace/