Number of occurrences of a character or string within a string

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Number of occurrences of a character or string within a string

Jeff Lanzarotta
Hello,

Is there a regular expression statement or a vim function to return the
number of a specific character or string within a string?

Regards,

-Jeff
Reply | Threaded
Open this post in threaded view
|

Re: Number of occurrences of a character or string within a string

Bugzilla from peterp@stack.nl
Op maandag 27 juni 2005 14:26, schreef Jeff Lanzarotta:
> Hello,

Hi,

> Is there a regular expression statement or a vim function to return the
> number of a specific character or string within a string?

Take a look at
:help count-items

Regards,


Peter Palm
Reply | Threaded
Open this post in threaded view
|

Re: Number of occurrences of a character or string within a string

James Vega-3
In reply to this post by Jeff Lanzarotta
On Mon, Jun 27, 2005 at 05:26:24AM -0700, Jeff Lanzarotta wrote:
> Is there a regular expression statement or a vim function to return the
> number of a specific character or string within a string?

Using a little vim scripting, you could write a function that does that.

:he stridx()
:he matchend()
:he script

James
--
GPG Key: 1024D/61326D40 2003-09-02 James Vega <[hidden email]>

signature.asc (204 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Number of occurrences of a character or string within a string

Tim Chase-2
In reply to this post by Bugzilla from peterp@stack.nl
>> Is there a regular expression statement or a vim function to
>> return the number of a specific character or string within a
>> string?
>
> Take a look at
> :help count-items

While the help found at "count-items" works for counting the
number of instances of a regexp in the document (or a range), the
OP seems to be asking for something that can be used in an
evaluation to count the number of instances in an arbitrary string.

Something like the following:

        :echo strlen(substitute("this is a string", "[^s]", "","g"))

returns "3" as the count of the letter "s" in the string "this is
a string".  Thus, this is expandible to things like

The number of "s" or "t" characters:

strlen(substitute("this is a string", "[^st]", "","g"))

The number of "s" or "t" characters, ignoring case:

strlen(substitute("This is a String", "[^st]", "","gi"))

or at least that last one *should* work.  It's failing on my
vim6.0 here at work, even though doing a simple

        :s/[^st]//gi

on a single line containing "This is a String" leaves 5
characters on the line, the above function returns 3 characters.
  Bug?

For a workaround, one could use

strlen(substitute("This is a String", "[^st]\\c", "","g"))

which properly returns "5"

Or, if you wanted to count things that *weren't* the letter "s"
or "t", then you could just remove the carat from the regexp.

Hope this gives some ideas,

-tim





Reply | Threaded
Open this post in threaded view
|

Re: Number of occurrences of a character or string within a string

Bugzilla from peterp@stack.nl
Op maandag 27 juni 2005 15:00, schreef Tim Chase:

> >> Is there a regular expression statement or a vim function to
> >> return the number of a specific character or string within a
> >> string?
> >
> > Take a look at
> >
> > :help count-items
>
> While the help found at "count-items" works for counting the
> number of instances of a regexp in the document (or a range), the
> OP seems to be asking for something that can be used in an
> evaluation to count the number of instances in an arbitrary string.

Ah, indeed.

Let's blame it on the lack of caffeine :)

> Something like the following:
> :echo strlen(substitute("this is a string", "[^s]", "","g"))
>
> returns "3" as the count of the letter "s" in the string "this is
> a string".  Thus, this is expandible to things like
>
> The number of "s" or "t" characters:
>
> strlen(substitute("this is a string", "[^st]", "","g"))
>
> The number of "s" or "t" characters, ignoring case:
>
> strlen(substitute("This is a String", "[^st]", "","gi"))
>
> or at least that last one *should* work.  It's failing on my
> vim6.0 here at work, even though doing a simple
>
> :s/[^st]//gi
>
> on a single line containing "This is a String" leaves 5
> characters on the line, the above function returns 3 characters.
>   Bug?

No, the documentation says the following about substitute()

When {flags} is "g", all matches of {pat} in {expr} are replaced. Otherwise
{flags} should be "".

Which is a little weird.

How can we substitute case-insensitive using substitute() ?


Peter Palm
Reply | Threaded
Open this post in threaded view
|

Re: Number of occurrences of a character or string within a string

Antony Scriven
In reply to this post by Tim Chase-2
On Jun 27, Tim Chase wrote:

   [I don't know who these are attributed to, sorry]
 > >>Is there a regular expression statement or a vim function to
 > >>return the number of a specific character or string within a
 > >>string?
 > >
 > >Take a look at
 > > :help count-items
 >
 > [...]
 >
 > The number of "s" or "t" characters, ignoring case:
 >
 > strlen(substitute("This is a String", "[^st]", "","gi"))
 >
 > or at least that last one *should* work.  It's failing on my
 > vim6.0 here at work, even though doing a simple
 >
 > :s/[^st]//gi
 >
 > on a single line containing "This is a String" leaves 5
 > characters on the line, the above function returns 3 characters.
 >  Bug?

According to :help substitute(), only 'g' is a valid flag.
Using \c in the regexp or switching on 'ignorecase' should
work.

 > For a workaround, one could use
 >
 > strlen(substitute("This is a String", "[^st]\\c", "","g"))

Ah, you've done it! (  '[^st]\c'  would also work.)

 > which properly returns "5"
 >
 > Or, if you wanted to count things that *weren't* the letter "s"
 > or "t", then you could just remove the carat from the regexp.
 > Hope this gives some ideas,

This following technique seems to work well for a multitude
of things. For this case in particular it will allow you to
count arbitrarily complex regexps.

   call substitute(str, pat, '\=SomeHelperFunction()', 'g')

Antony
Reply | Threaded
Open this post in threaded view
|

Re: Number of occurrences of a character or string within a string

Tim Chase-2
In reply to this post by Bugzilla from peterp@stack.nl
> No, the documentation says the following about substitute()
>
> When {flags} is "g", all matches of {pat} in {expr} are
> replaced. Otherwise {flags} should be "".

my error for missing that bit in the help. :(

> How can we substitute case-insensitive using substitute() ?

As my later work-around, and Antony Scriven later noted, you can
append "\c" to the search pattern to make it ignore case. If you
use double-quotes, then you have to escape the back-slash, but if
you use single-quotes, you don't have to.

Though I still find it peculiar that substitute() doesn't allow
options other than "g". :-/

-tim





Reply | Threaded
Open this post in threaded view
|

Re: Number of occurrences of a character or string within a string

Jeff Lanzarotta
In reply to this post by Antony Scriven
Thanks for everyone's help, your suggestions work just fine in my code.

-Jeff

--- Antony Scriven <[hidden email]> wrote:

> On Jun 27, Tim Chase wrote:
>
>    [I don't know who these are attributed to, sorry]
>  > >>Is there a regular expression statement or a vim function to
>  > >>return the number of a specific character or string within a
>  > >>string?
>  > >
>  > >Take a look at
>  > > :help count-items
>  >
>  > [...]
>  >
>  > The number of "s" or "t" characters, ignoring case:
>  >
>  > strlen(substitute("This is a String", "[^st]", "","gi"))
>  >
>  > or at least that last one *should* work.  It's failing on my
>  > vim6.0 here at work, even though doing a simple
>  >
>  > :s/[^st]//gi
>  >
>  > on a single line containing "This is a String" leaves 5
>  > characters on the line, the above function returns 3 characters.
>  >  Bug?
>
> According to :help substitute(), only 'g' is a valid flag.
> Using \c in the regexp or switching on 'ignorecase' should
> work.
>
>  > For a workaround, one could use
>  >
>  > strlen(substitute("This is a String", "[^st]\\c", "","g"))
>
> Ah, you've done it! (  '[^st]\c'  would also work.)
>
>  > which properly returns "5"
>  >
>  > Or, if you wanted to count things that *weren't* the letter "s"
>  > or "t", then you could just remove the carat from the regexp.
>  > Hope this gives some ideas,
>
> This following technique seems to work well for a multitude
> of things. For this case in particular it will allow you to
> count arbitrarily complex regexps.
>
>    call substitute(str, pat, '\=SomeHelperFunction()', 'g')
>
> Antony
>