How to Find and Replace a value bigger than 100(Float)
-
This is pretty easy with JsonTools, which I would recommend over other mathematical replacement tools because you appear to be working with JSON.
If you want to replace all values greater than 100 that are associated with the
Value
key, no matter where thatValue
key is in the document, the RemesPath query@..Value[and(is_num(@), @ > 100)] = 1.0
will do the job. If that’s not quite what you’re looking for, you need to tell us more about the structure of your JSON. -
This is a .umap (Unreal Engine 4) file extracted to .json. I want to reduce the intensity of point light in a map i’m working on, so it needs to have the “intensity” when I search to replace, otherwise it will overwrite other important values.
Give me this error when i try to replace:
“Runtime error while executing query
While executing query @…Value[and(is_num(@), @ > 100)] = 1.0, encountered runtime error:
System.ArgumentException: Cannot compare JArrays or JObjects
at JSON_Tools.JSON_Tools.JNode.CompareTo(Object other)
at JSON_Tools.JSON_Tools.JNode.CompareTo(Object other)
at JSON_Tools.JSON_Tools.Binop.GreaterThan(JNode a, JNode b)
at System.Linq.Enumerable.WhereSelectListIterator2.MoveNext() at System.Collections.Generic.List
1…ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable
1 source)
at JSON_Tools.JSON_Tools.Binop.BinopJsonScalar(JNode left, JNode right)
at JSON_Tools.JSON_Tools.Binop.BinopTwoJsons(JNode left, JNode right)
at JSON_Tools.JSON_Tools.ArgFunction.And(List1 args) at JSON_Tools.JSON_Tools.IndexerFunc.<>c__DisplayClass6_0.<<ApplyBooleanIndex>g__boolIdxrFunc|0>d.MoveNext() at JSON_Tools.JSON_Tools.RemesParser.<ApplyIndexerList>g__idxrListFunc|16_0(JNode obj, List
1 idxrs, Int32 ii)
at JSON_Tools.JSON_Tools.RemesParser.<ApplyIndexerList>g__idxrListFunc|16_0(JNode obj, List`1 idxrs, Int32 ii)
at JSON_Tools.JSON_Tools.JMutator.Operate(JNode inp)
at JSON_Tools.Forms.TreeViewer.SubmitQueryButton_Click(Object sender, EventArgs e)” -
Give me this error when i try to replace:…
Yeah, there was a typo in my query, but it doesn’t matter because my query would not be adequately restrictive.
I want to reduce the intensity of point light in a map i’m working on, so it needs to have the “intensity” when I search to replace, otherwise it will overwrite other important values.
I still don’t understand what you’re going for, but at this point I no longer think this is an appropriate task for a Notepad++ plugin, and you need to figure out how to do this in a programming language.
-
@Google-Sync said in How to Find and Replace a value bigger than 100(Float):
I want to find and replace a value greater than 100.0 with 1.0?
2 Lines.
"Value": 100.0, "Name": "Intensity",
If:
- the structure is always as you’ve shown;
- “Value” and “Name” always occur next to each other, in that order;
- the values never have leading zeros;
- you meant greater than or equal to 100;
then you can do this:
From the main menu, select Search | Replace…; in the dialog, enter:
Find what:
(?<="Value")\s*:\s*\d\d\d[.\d]*(?=\s*,\s*"Name"\s*:\s*"Intensity")
Replace with:: 1.0
Match case: checked or not, depending on whether case matters in your file
Wrap around: checked
Search mode: Regular expressionand then click Replace All.
-
It worked flawless, Thank u.
Now, if I want to replace something greater than 25.0, how do I put it? Just so I can try to understand how this language works.
-
@Google-Sync said in How to Find and Replace a value bigger than 100(Float):
“Value”: 100.0,
There is insufficient information in your post to generate a regular expression that will reliably match “value bigger than 100(Float).”
Specifically, you have not shown when values less than or equal to “100(Float)” are in your data. You have also not shown how values exactly equal to “100(Float)” may be formatted in your data. You have also not shown how values larger or bigger than “100(Float)” may be formatted in your data.
Computers and regular expressions have an annoying habit of doing exactly what you tell them to do, which is often not exactly what you wanted.
As you did not provide much in the way of example data or possible edge conditions I will take a big guess at what your data may have and for now will only focus on the
"Value": 100.0,
part of the problem.Let’s start with
values that are a tiny bit larger than 100 which I'll match with
“Value”: 100.0*[1-9][0-9]*,That will match on
"Value": 100.00000000000001,for example as it's a number that is
0.00000000000001` bigger than 100.Match on 101 to 109 using
"Value": 10[1-9](?:\.[0-9]*)?,
Match on 110 to 199 using
"Value": 1[1-9][0-9](?:\.[0-9]*)?,
Match on 1000 or more using
"Value": [1-9][0-9]{3,}(?:\.[0-9]*)?,
Now we have identified four regexp that will match values that are a fraction larger than 100, that are ones larger than 100, that are tens larger than 100, and finally that are four or more digits which are numbers that must be larger than 100. Let’s combine all four and we have
"Value": (?:100\.0*[1-9][0-9]*|(?:10[1-9]|1[1-9][0-9]|[1-9][0-9]{3,})(?:\.[0-9]*)?),
That can be painful for humans to read and so I’ll spread it out over several lines.(?x)"Value":\x20 (?: 100\.0*[1-9][0-9]*| # Match 100. followed by at least one non-zero digit after the decimal point (?: 10[1-9]| # Match 101 to 109 1[1-9][0-9]| # Match 110 to 199 [1-9][0-9]{3,} # Match 1000 or more )(?:\.[0-9]*)? # Allow for the values 101 to 1000 or more to have a decimal point followed by zero or more digits ),
The human readable version works in Notepad++ if you want to experiment with it. Keep in mind that if you want to match a space then you need to use
\x20
as I did in the first line to match the space that is after"Value":
While you can’t do math or math style comparisons in regular expressions you can somewhat simulate the desired behavior using what I showed above.
-
Since @Google-Sync still hasn’t explained what they want, I guess I’ll start ranting about JSON and what I mean when I ask about
the structure of your JSON
.Consider this JSON object:
{ "foo": {"value": 1, "name": "foo"}, "bar_array": [{"value": 1, "name": "foo"}] }
With a JSON parser, it is quite easy to differentiate between the two instances of
{"value": 1, "name": "foo"}
in that object, but I, as an outsider trying to guess how to help the person working with this JSON, need to see this entire JSON object, not just a small subset of it. -
@Mark-Olson said in How to Find and Replace a value bigger than 100(Float):
Since @Google-Sync still hasn’t explained what they wan
Sorry, until a user gets upvotes, their replies are at the mercy of moderator availability… That user had tried to reply in a more timely manner, as can be seen by where it got inserted…
I highly recommend to all people answering, that if you think the OP has put in a reasonable effort and doesn’t appear to be a spammer, and you want them to be able to reply to your requests for clarification, that you make sure that they get at least one upvote…
-
Now, if I want to replace something greater than 25.0, how do I put it? Just so I can try to understand how this language works.
That one is harder. For the >= 100.0 case, that could be shortcut by saying “any number with three or more digits before the decimal”, which is how @Coises crafted a non-mathematical regex to do it.
Using the ideas that @mkupper suggested, you could craft a regex for choosing a different threshold, but every threshold would take a lot of manual crafting, which is why I made the blanket statement that NPP cannot do it natively, because it cannot do it generically.
However, using one of the plugins suggested in the FAQ, you could actually include a mathematical comparison in the search expression, which you cannot do in Notepad++'s native regex searches. This is why I recommended the FAQ, as it explains all that, and gives examples of how to do similar actions in three different plugins.
-
@Google-Sync said in How to Find and Replace a value bigger than 100(Float):
Now, if I want to replace something greater than 25.0, how do I put it? Just so I can try to understand how this language works.
That’s trickier. The expression given took advantage of the fact that if there are no leading zeros, any number with three or more digits before the decimal point must be greater than or equal to 100. This bit:
\d\d\d[.\d]*
matches three digits, followed by zero or more digits or decimal points.To match 25 or greater, we’d need to break that down into numbers with three or more digits, numbers with two digits where the first one is 3-9 and numbers with two digits where the first one is 2 and the second one is 5-9. That could look like this:
(\d\d\d+|[3-9]\d|2[5-9])[.\d]*
making the whole thing look like this:
(?<="Value")\s*:\s*(\d\d\d+|[3-9]\d|2[5-9])[.\d]*(?=\s*,\s*"Name"\s*:\s*"Intensity")
Now, if you really mean greater than 25 (not greater than or equal to), you’d need to separate out the 25 case as well and make sure it is followed by a decimal point and a string of digits at least one of which is not 0.
For references to how regular expressions work, see the Notepad++ User Manual section on regular expressions.
-
FWIW, JsonTools v8.3.1.3 (see instructions for downloading an unreleased version) now has a function that would allow JsonTools to solve this problem without knowing the full structure of the JSON document.
recurse_until(@, and(@.Value > 100, @.Name == Intensity))[:].Value = 1.0
will convert all theValue
instances greater than 100 where theName
wasIntensity
to1.0
.For example, in
{"foo": [{"Value": 101, "Name": "Intensity"}, {"Name": "Blah", "Value": 200}], "bar": {"Name": "Intensity", "Value": 60}}
, running this query would return{"foo": [{"Value": 1.0, "Name": "Intensity"}, {"Name": "Blah", "Value": 200}], "bar": {"Name": "Intensity", "Value": 60}}
I should note that the
recurse_until
method is very slow compared to other JsonTools functions because it can potentially throw and catch an exception for every node in a document, so I do not endorse this approach for very large documents.