• Login
Community
  • Login

Search a number grater than

Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
9 Posts 5 Posters 2.8k Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V
    Vitor Fessel
    last edited by May 18, 2023, 7:26 PM

    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?

    A P N 3 Replies Last reply May 18, 2023, 7:58 PM Reply Quote 0
    • A
      Alan Kilborn @Vitor Fessel
      last edited by Alan Kilborn May 18, 2023, 8:01 PM May 18, 2023, 7:58 PM

      @Vitor-Fessel

      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 expression

      You didn’t say exactly how the Length: part comes into it, but if it is like Length:35 then just put Length: 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.

      1 Reply Last reply Reply Quote 1
      • P
        PeterJones @Vitor Fessel
        last edited by PeterJones May 18, 2023, 8:01 PM May 18, 2023, 8:00 PM

        @Vitor-Fessel ,

        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.

        A 1 Reply Last reply May 18, 2023, 8:04 PM Reply Quote 2
        • A
          Alan Kilborn @PeterJones
          last edited by May 18, 2023, 8:04 PM

          @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.

          P 1 Reply Last reply May 18, 2023, 9:21 PM Reply Quote 1
          • N
            Neil Schipper @Vitor Fessel
            last edited by Neil Schipper May 18, 2023, 8:17 PM May 18, 2023, 8:16 PM

            @Vitor-Fessel

            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 expression 0*(?:[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
            
            1 Reply Last reply Reply Quote 1
            • P
              PeterJones @Alan Kilborn
              last edited by PeterJones May 18, 2023, 9:24 PM May 18, 2023, 9:21 PM

              @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 for r'Length: (\d+) and have the callback use group index 1 instead of 0 throughout, to meet @Vitor-Fessel’s requirements.

              A 1 Reply Last reply May 19, 2023, 11:52 AM Reply Quote 2
              • A
                Alan Kilborn @PeterJones
                last edited by May 19, 2023, 11:52 AM

                @PeterJones

                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())
                
                P M 2 Replies Last reply May 19, 2023, 1:50 PM Reply Quote 2
                • A Alan Kilborn referenced this topic on May 19, 2023, 11:52 AM
                • P
                  PeterJones @Alan Kilborn
                  last edited by May 19, 2023, 1:50 PM

                  @Alan-Kilborn said in Search a number grater than:

                  @PeterJones

                  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 every editor.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.

                  1 Reply Last reply Reply Quote 0
                  • M
                    Mark Olson @Alan Kilborn
                    last edited by May 19, 2023, 2:46 PM

                    @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.
                    63ddf9b8-22a9-411a-8448-33a055dcf3fa-image.png

                    # -*- 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()
                    
                    1 Reply Last reply Reply Quote 3
                    • M Mark Olson referenced this topic on May 19, 2023, 2:46 PM
                    6 out of 9
                    • First post
                      6/9
                      Last post
                    The Community of users of the Notepad++ text editor.
                    Powered by NodeBB | Contributors