Find and Replace with increments
-
I have a text file that is made up of roughly 500+ of the following repeating format:
{ "valueSource": "opc", "historyTimeDeadband": 5, "opcItemPath": "ns\u003d1;s\u003d[Extruder19]Master_die_zone_1.PVHAlarm", "historicalDeadband": 0.5, "alarms": [ { "setpointA": 1.0, "name": "Master die zone 1 PVHAlarm", "priority": "High", "displayPath": "Extruder19" } ], "historicalDeadbandStyle": "Discrete", "tagGroup": "Default", "historyTagGroup": "Alarm Historical", "tagType": "AtomicTag", "dataType": "Boolean", "historyProvider": "BOL_IgnitionDB", "name": "Master_die_zone_1_PVHAlarm", "historyEnabled": false, "sampleMode": "TagGroup", "opcServer": "Ignition OPC UA Server" },For this, they are all the exact same right now, but I want to change some parts of it. Wherever it says “zone_1” (Lines 4,9, and 20) it need to replace it with “zone” + incrementing numbers, so the second group of this would read “zone_2”, the third will read “zone_3” and so on. What is a way I can do that using notepad++?
-
With just Notepad++ and nothing else, you cannot: the replacement engine cannot “auto increment”. If you are willing to use a plugin, it’s easy.
You can install the PythonScript plugin, and use the example
add_1that’s in the documentation; you’d have to change the search regular expression in the script to suit your needs (off the top of my head, without trying, it would be something liker'zone_(\d+)'for the search string)This FAQ entry describes how to install the PythonScript plugin and create a new script in PythonScript. And using Plugins > Python Script > Context-Help will take you to the documentation, and searching that documentation for
add_1will take you to the example script.Please note that the example in the documentation adds one to the number found in the search; what you want is a
counterthat adds one to the previous value of the counter and replaces the found string with a string based on that counter instead.You can search this forum for examples of
add_1and related pythonscript replacements … and I think this post probably contains close to what you want in terms of thecounter. -
@peterjones thank you for the detailed response, Apologize if this is a stupid question but how would I make the python code for notepad++? I have used python before but never for notepad++ so I am not sure how it works at all. Would I just write “editor.rereplace(r’zone (\d+)', add_1)” on the python file?
-
how would I make the python code for notepad++? …
I rather thought I already answered that in my last post and the FAQ entry that I pointed you to. Plus the other discussion, with the
counterexample has the step-by-step detailed instructions embedded in the script to copy/paste. I am not sure how much more explicit about the process that I can be.Would I just write … on the python file?
If I assume that by “on the python file” meant “inside the file that I created when I followed the instructions in the FAQ, and on the line that currently has the
editor.rereplacefrom that script”, then yes.When I noticed that you had typed without an underscore in your reply, I looked back and now see that in your example data, lines 4 and 20 have the underscore but line 9 does not, so my guess at an expression will definitely not work for you. And that there is more than one instance of
zone_#in each block, so I am now assuming that you really want to maintain the same # within each top-level{...}block.That’s much more complicated than I originally understood it, and a simple change to the
counterexample won’t be sufficient for your needs. -
I think this script will do what you want
# encoding=utf-8 """https://community.notepad-plus-plus.org/topic/23149/find-and-replace-with-increments/4 This will start by matching text from `{` at the beginnig of a line to `}` or `},` at the beginning of a line Inside those groups, it will replace all "zone_#" or "zone #" with the value of the counter The counter will increment between `{...}` groups """ from Npp import * import re counter = 1 def replace_group(m): global counter out = re.sub(r'(?<=zone[ _])\d+', str(counter), m.group(0)) counter = counter + 1 return out console.clear() editor.beginUndoAction() editor.rereplace(r'(?s)^{\h*$.*?^},?\h*$', replace_group) editor.endUndoAction()The
editor.rereplaceline matches from{at the beginning of a line to}or},at the beginning of a line. It then callsreplace_group()on that match. The second function does the search-and-replace inside that group, looking forzonefollowed by either_or space, followed by one or more digits, and replaces those digits with the current value of the counter. Every group of{to},will increment the counter by one, so each chunk will get a unique number, but use the same number inside.Assumptions:
- That your example data isn’t missing leading spaces, because the regex assumes the
{and},are at the beginning of the line.- That there aren’t any other
{and},at the beginning of lines embedded inside (so nicely indented and properly formulated json)
- That there aren’t any other
- That
zone_1andzone 1within a single {…} block should all get the same counter value - That you don’t have any
zone_###inside your blocks that you don’t want changed (you didn’t show any, but…)
- That your example data isn’t missing leading spaces, because the regex assumes the
-
P PeterJones referenced this topic on
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login