Search a number grater than
-
how to perform a search in a txt file, for a number greater than or equal to 25 of a specific variable, using Find?
Example:
Variable: "Length: "
Search: “>= 25”
How to set up search in Find? Which options should I use? -
You won’t like the answer; it isn’t trivial.
Here’s one possible way:
Find:
\b(\d{3,}|2[5-9]|[3-9]\d)\b
Search mode: Regular expressionYou didn’t say exactly how the
Length:
part comes into it, but if it is likeLength:35
then just putLength:
at the front of the expression.However, this is probably going to end up where you are doing json or xml or some such, in which case, using raw Notepad++ find (or replace) may not be the route in which to go.
-
Notepad++'s search doesn’t do math (including numeric value greater than): numbers are just characters to the search/replace engine.
If Alan’s regex (regular expression search) isn’t sufficient for you, we’ve got a FAQ that explains how to use a plugin and some programming (on your part) to do the math.
-
@PeterJones said in Search a number grater than:
we’ve got a FAQ that explains how to use a plugin and some programming (on your part) to do the math.
The FAQ only shows techniques for replacing, and OP only mentioned finding … thus far. For just finding and doing “real math”, we don’t have a canned solution / good examples for that.
-
If you wish to include leading 0’s in the match, or if you wish to tolerate non-digits adjacent to the digits on either side, you could use
find expression0*(?:[3-9]\d|2[5-9])\d*
It implements this logic:
<optional leading zeros> ( <a digit in range 3-9 followed by at least one digit> or <a 2 followed by a digit in range 5-9> ) <optional trailing digits>
It can be tested against:
00004 00004z x00004 000014 000024 000025 000026 v000026 000026b 0090026 0090026054875f
-
@Alan-Kilborn said in Search a number grater than:
thus far.
Challenge accepted.
# encoding=utf-8 """https://community.notepad-plus-plus.org/post/86443 Bookmark any line that starts with an integer greater than or equal to 25. """ from Npp import editor, notepad, MENUCOMMAND import re # to be able to use Python's regular expression library def custom_match_func(m): i = int(m.group(0)) if i >= 25: editor.setSel( m.start(0), m.end(0) ) notepad.menuCommand(MENUCOMMAND.SEARCH_TOGGLE_BOOKMARK) # really should check bookmark status first, and have it # only toggle if it's not already bookmarked # but that goes beyond the scope of this FAQ # notepad.menuCommand(MENUCOMMAND.SEARCH_CLEAR_BOOKMARKS) # optionally clear bookmarks before this search editor.research(r'^\b\d+\b', custom_match_func) """ Here is example data to test it on: 1. Here Here is 25 25 here This line should match Yep 99999 is OK So should this one """
This can be easily customized in the
editor.research()
line to look forr'Length: (\d+)
and have the callback use group index 1 instead of 0 throughout, to meet @Vitor-Fessel’s requirements. -
Minor point but by “thus far” I meant that the OP hadn’t expressed any “replacing” desire (only finding), not that the “math faq” entry hasn’t shown how to do anything but replaces.
The bookmarking approach is “okay” but it might rub someone that wants a step-by-step find or a “find all” the wrong way.
Find-all is difficult to implement because scripts can’t really add output to the Search results window. :-(
However, step-by-step find, aka “Find Next” is reasonable; here’s my take on it; every time it is run it finds the next value that meets the spec:
# -*- coding: utf-8 -*- # references: # https://community.notepad-plus-plus.org/topic/24481 from Npp import * def custom_match_func(m): if custom_match_func.stop: return i = int(m.group(0)) if i >= 25: editor.setSel(m.start(0), m.end(0)) custom_match_func.stop = True custom_match_func.stop = False editor.research(r'\b\d+\b', custom_match_func, 0, editor.getCurrentPos())
-
-
@Alan-Kilborn said in Search a number grater than:
Minor point but by “thus far” I meant that the OP hadn’t expressed any “replacing” desire (only finding), not that the “math faq” entry hasn’t shown how to do anything but replaces.
Oh, okay. Well, it was still actually a deficiency in the FAQ, so… ;-)
The bookmarking approach is “okay” but it might rub someone that wants a step-by-step find or a “find all” the wrong way.
I agree. Doing the bookmark was just my compromise between find-next and find-all, because “bookmark all” would allow a user to use the next/previous bookmark to then navigate between results.
Find-all is difficult to implement because scripts can’t really add output to the Search results window. :-(
My thought for a Find All would be to do a multi-selection to put all the matches in a single selection, though that’s probably not actually what would be natural, either.
However, step-by-step find, aka “Find Next” is reasonable; here’s my take on it; every time it is run it finds the next value that meets the spec:
Interesting that you chose to do a toggle. Why not just set the maxCount parameter of
editor.research
to 1? (… some experimenting later…) Oh, right, because not everyeditor.research
match also matches the internal math restriction, so in my example file, since the first number that matches wasn’t big enough, the selection didn’t move forward, which meant that when I ran it a second time, it started from the old caret not the new caret, and got in an infinite loop of finding the first number but not selecting it; that should have been more obvious to me than it was. -
@Alan-Kilborn
With your script as inspiration, I made one that has a different custom search func for each file, allows the user to set the search func with selected text, and the user can choose whether or not to bookmark lines.
# -*- coding: utf-8 -*- # references: # https://community.notepad-plus-plus.org/topic/24481 from Npp import * import operator import re # Too lazy to parse config files; just modify these global variables instead BOOKMARK_LINES = True class FBOLTN: def __init__(self): self.set_comparator() def set_comparator(self): comparator_regex = re.compile("([><]=?|=)(-?\d+)") sel = editor.getSelText() mtch = comparator_regex.search(sel) if mtch: # user is selecting a new comparator compstr, numstr = mtch.groups() num = int(numstr) else: if hasattr(self, 'comparator'): return # only override current comparator with valid selection # default is what the OP wanted compstr = '>=' num = 25 self.compstr = compstr self.num = num def comparator(other_num): fun = { '>': operator.gt, '<': operator.lt, '=': operator.eq, '>=': operator.ge, '<=': operator.le, }[compstr] return fun(other_num, num) self.comparator = comparator def custom_match_func(self, m): if self.stop: return i = int(m.group(0)) start, end = m.start(0), m.end(0) if self.comparator(i): editor.setSel(start, end) if BOOKMARK_LINES: notepad.menuCommand(MENUCOMMAND.SEARCH_TOGGLE_BOOKMARK) self.stop = True def search(self): self.stop = False editor.research(r'(?<!\w)-?\d+\b', self.custom_match_func, 0, editor.getCurrentPos()) if __name__ == '__main__': try: fboltns except NameError: fboltns = {} cur_fname = notepad.getCurrentFilename() if not fboltns.get(cur_fname): fboltns[cur_fname] = FBOLTN() fboltn = fboltns[cur_fname] fboltn.set_comparator() fboltn.search()
-