Loading ...
Sorry, an error occurred while loading the content.
 

Finding the nth occurrence of a string/char in a string

Expand Messages
  • Jeff Lanzarotta
    Hello, How would you find the nth occurrence of a string/char in a string? For example: If I have the string abcdabcdabcd and I want to get the offset to
    Message 1 of 3 , Jan 3, 2002
      Hello,

      How would you find the nth occurrence of a string/char in a string?

      For example: If I have the string 'abcdabcdabcd' and I want to get the
      offset to there the 2nd 'c' is, how would one do that?

      Any ideas?

      --
      Jeff Lanzarotta
      ~
      ~
      ~
    • Charles E. Campbell
      ... [^c] {-}c * this pattern matches a minimal amount of not-c up to the letter c {1} * will match up to one of the preceding regexp sub-expression
      Message 2 of 3 , Jan 3, 2002
        Thus saith Jeff Lanzarotta:
        > How would you find the nth occurrence of a string/char in a string?
        >
        > For example: If I have the string 'abcdabcdabcd' and I want to get the
        > offset to there the 2nd 'c' is, how would one do that?
        ---------------------------------------------------------------------

        [^c]\{-}c * this pattern matches a minimal amount of not-c up to
        the letter c
        \{1} * will match up to one of the preceding regexp
        sub-expression (ie. if you wanted to find the n'th,
        use \{n-1} here)
        \zs * anything before this is leading-context; sets start
        of match
        \(...\) * groups innards into a regexp sub-expression

        OK, with these regexp tools, let's put something together:

        /\([^c]\{-}c\)\{1}[^c]\{-}\zsc/

        Seems to work!
        Charles Campbell

        --
        Charles E Campbell, Jr, PhD _ __ __
        Goddard Space Flight Center / /_/\_\_/ /
        cec@... /_/ \/_//_/
        PGP public key: http://www.erols.com/astronaut/pgp.html
      • Zdenek Sekera
        ... Here are two useful useful functions I use for this exact purpose, the idea comes originally from Michael Geddes. StringN.vim ...
        Message 3 of 3 , Jan 3, 2002
          Jeff Lanzarotta wrote:
          >
          > Hello,
          >
          > How would you find the nth occurrence of a string/char in a string?
          >
          > For example: If I have the string 'abcdabcdabcd' and I want to get the
          > offset to there the 2nd 'c' is, how would one do that?
          >
          > Any ideas?

          Here are two useful useful functions I use for this exact purpose, the
          idea comes originally from Michael Geddes.


          StringN.vim
          -----------

          "-------------------------------------------------------------------------------
          " StringN() - get the position and sequence number of the n-th
          appearance of
          " a string in the text
          "-------------------------------------------------------------------------------
          "
          " Function:
          " StringN(text, string, n)
          "
          " Call:
          " let pos = StringN(text, string, n)
          "
          " Where:
          " text - string to search for the 'string'
          " string - string to be found in the 'text'
          " n - the n-th position of 'string' in 'text' should be
          returned
          "
          " External variables:
          " None.
          "
          " Returns:
          " 0 - if the n-th appearance of the 'string' was found
          " -1 - if the n-th appearance of the 'string' was not found
          " -2 - if the 'n' <= 0
          "
          " Also always returns:
          " g:TOOLpos - the position of the n-th 'string' (return code rc =
          0)
          " the position of the last occurence of string (rc =
          -1)
          " g:TOOLnum - the 'n' if n-th position found (trivial) (rc =
          0)
          " the total number found (rc =
          -1)
          "
          " Description:
          " Takes the 'string' and searches for it's appearance in the
          " 'text' repeatedly. The n-th appearance is reported.
          "
          " Example:
          " let a = "aa<>qqq<>#<>"
          " let pos = StringN(a, '<>', 2)
          " will report pos = 7
          "
          " Notes:
          " This is really invention of Michael Geddes.
          " It speeds up e.g. ARR package tremendeously.
          "
          " Modifications:
          " Initial version: Jun/14, 2000 by ZS
          "
          " Author: Zdenek Sekera/zs@... Date: Jun/14, 2000
          "
          "-------------------------------------------------------------------------------

          function! StringN(text, string, n)
          if a:n <= 0
          return -2
          endif
          let mx = '^\(\(.\{-}'.a:string.'\)\{'.a:n.'}\).*$'
          let my = '^\(.*\)'.a:string.'$'

          " the following will return pos=0 if 'string' doesn't
          " exist in the 'text' at all or n is greater than the
          real
          " number of occurences.
          " Maybe useful sometimes but the next version of it may
          " be easier to parse.......
          " let pos = strlen(substitute
          "
          \(substitute(matchstr(a:text,mx),mx,'\1',''),my,'\1',''))

          let pos = strlen(substitute
          \(substitute(a:text,mx,'\1',''),my,'\1',''))
          if pos + strlen(a:string) >= strlen(a:text) - 1
          let p = StringLast(a:text, a:string)
          if a:n != g:TOOLnum
          return -1
          endif
          endif
          let g:TOOLpos = pos
          let g:TOOLnum = a:n
          return 0
          endfunction

          "-------------------------------------------------------------------------------
          " vim: ts=8:sw=4:sts=4:tw=0:ft=vim


          StringLast.vim
          --------------

          "-------------------------------------------------------------------------------
          " StringLast() - get the position and sequence number of the last
          appearance
          " of a string in the text
          "-------------------------------------------------------------------------------
          "
          " Function:
          " StringLast(text, string)
          "
          " Call:
          " let pos = StringLast(text, string)
          "
          " Where:
          " text - string to search for the 'string'
          " string - string to be found in the 'text'
          "
          " External variables:
          " None.
          "
          " Returns:
          " 0 - if the last appearance of the 'string' was found
          " -1 - otherwise
          "
          " Also always returns:
          " g:TOOLpos - the position of the last 'string' (return code rc =
          0)
          " -1 if the 'string' was not found at all (rc =
          -1)
          " g:TOOLnum - the 'n' of the last 'string' appearance (rc =
          0)
          " 0 if the 'string' was not found at all (rc =
          -1)
          "
          " Description:
          " Takes the 'string' and searches for it's appearance in the
          " 'text' repeatedly. The last appearance is reported together
          " with its sequential number.
          "
          " Example:
          " let a = "aa<>qqq<>#<>"
          " let pos = StringLast(a, '<>')
          " will report pos = 10
          " g:TOOLnum = 3
          "
          " Notes:
          " This is really invention of Michael Geddes.
          " It speeds up e.g. ARR package tremendeously.
          "
          " Modifications:
          " Initial version: Jun/14, 2000 by ZS
          "
          " Author: Zdenek Sekera/zs@... Date: Jun/14, 2000
          "
          "-------------------------------------------------------------------------------
          function! StringLast(text, string)
          let mx = '^\(\(.*\)'.a:string.'\).\{-}$'
          let pos = strlen(substitute(a:text,mx,'\2',''))
          let num = strlen(substitute

          \(substitute(a:text,mx,'\1',''),'.\{-}'.a:string,'|','g'))
          if pos == num && pos == strlen(a:text)
          " not found
          let g:TOOLpos = -1
          let g:TOOLnum = 0
          return -1
          else
          let g:TOOLpos = pos
          let g:TOOLnum = num
          return 0
          endif

          endfunction

          "-------------------------------------------------------------------------------
          " vim: ts=8:sw=4:sts=4:tw=0:ft=vim
        Your message has been successfully submitted and would be delivered to recipients shortly.