Matching words within X lines

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Matching words within X lines

A. Wik
Hi all,

I'm trying to match a couple (maybe more later) of words occurring
within 3 lines of each other in any order.  Is there a way to do this
with a Vim regex?

-Albert.

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/vim_use/CALPW7mRa2YyPseOHUH_ckoV-C16dkJFD230wW_%3Dq7Jp5fTsARQ%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Matching words within X lines

Tim Chase
On 2020-12-06 18:11, A. Wik wrote:
> I'm trying to match a couple (maybe more later) of words occurring
> within 3 lines of each other in any order.  Is there a way to do
> this with a Vim regex?

The short answer is "yes", but the specifics depend on what you mean.
Can the words come in any order?  Is this for just 2 words?  Or more
than two words?  If they're sets of words, does it count to find the
*same* word within N lines?

For two words in a fixed order (HI followed by BYE in the subsequent
3 lines), you can do something like

  /\<HI\>\%(.*\n\)\{,2}.*\<BYE\>

where the "2" is the N-lines-minus-1

For HI and BYE withing 3 lines but the order might be reversed (BYE
then HI), it's likely easiest to do the same thing with the "or"
conjunction:

  /\<HI\>\%(.*\n\)\{,2}.*\<BYE\>\|\<BYE\>\%(.*\n\)\{,2}.*\<HI\>

For arbitrary sets of words or patterns, followed by up to 3 lines,
such as HEY, HI, and BYE

  /\<\%(HI\|HEY\|BYE\)\>\%(.*\_.\)\{,2}.*\<\%(HEY\|HI\|BYE\)\>

though that could find instances where the first and second words are
the same such as "HI...HI".  If you want to make sure they are
different, you might use this monster

  /\<\(HI\|HEY\|BYE\)\>\%(.*\_.\)\{,2}.*\<\%(\1\>\)\@!\%(HEY\|HI\|BYE\)\>

which uses the "the thing we captured as the first word can't match
at the point where we find the second word" "\@!" token.

They're ugly, but vim will at least let you do them.

-tim




--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/vim_use/20201206202305.6067db6c%40bigbox.attlocal.net.
Reply | Threaded
Open this post in threaded view
|

Re: Matching words within X lines [PS]

Tim Chase
On 2020-12-06 20:23, Tim Chase wrote:
> They're ugly, but vim will at least let you do them.

Oh, one other caveat:  it only finds the bookends and starts the next
search after the closing bookend.  So if there is the possiblity that
the matches overlap, such as searching for "A...B" and you have

  A text A text B text B

it will find the first A through its corresponding B, but won't find
the second A because it has been eaten as part of the first match.
Not a grievous concern, but at least something to be aware of if
you're using it to do some sanity-/duplicate-checking on your
documents.

-tim


--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/vim_use/20201206202900.13489911%40bigbox.attlocal.net.
Reply | Threaded
Open this post in threaded view
|

Re: Matching words within X lines [PS]

A. Wik
On Mon, 7 Dec 2020 at 02:29, Tim Chase <[hidden email]> wrote:

>
> On 2020-12-06 20:23, Tim Chase wrote:
> > They're ugly, but vim will at least let you do them.
>
> Oh, one other caveat:  it only finds the bookends and starts the next
> search after the closing bookend.  So if there is the possiblity that
> the matches overlap, such as searching for "A...B" and you have
>
>   A text A text B text B
>
> it will find the first A through its corresponding B, but won't find
> the second A because it has been eaten as part of the first match.
> Not a grievous concern, but at least something to be aware of if
> you're using it to do some sanity-/duplicate-checking on your
> documents.

Thank you.

I'm using it to help find information in my diary.  Eg.: "For future
reference ... X".  The X is a keyword suggesting what the future
reference pertains to.

Now, I want to do the following

:redir @m
:g/future.*ref.*\n.*\n
:redir END

Alternatively, instead of redir, I can use [...]/y M at the end of the
:g command.

Alas, :g includes only the line matching "future.*ref".  I want to
capture the whole match.  Is there a way to do that?

-aw

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/vim_use/CALPW7mS_6KzL4OBWWCmHBPdeopfdFdT34iXW%2BCHyPJ1B6jCErQ%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Matching words within X lines [PS]

Gabriele Fava
On 07/12/2020 13.59, A. Wik wrote:

> Now, I want to do the following
> :redir @m
> :g/future.*ref.*\n.*\n
> :redir END
>
> Alternatively, instead of redir, I can use [...]/y M at the end of the
> :g command.
>
> Alas, :g includes only the line matching "future.*ref".  I want to
> capture the whole match.  Is there a way to do that?

It would seem that what's wrong with the first command is simply that
:p, which is the command used by default by :g, by itself prints only
*one* line. If you instead explicitly use :p {count}, e.g.
":g/future.*ref.*\n.*\n/p 3", it seems to work.

But, was this what you meant to ask in the first question, or an
additional issue?
«trying to match a couple (maybe more later) of words occurring within 3
lines of each other in any order» seems to mean more what Tim helped you
with...?


Gabriele

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/vim_use/4ce70bdd-4ea7-0215-2454-e90227c83bb6%40tiscali.it.
Reply | Threaded
Open this post in threaded view
|

Re: Matching words within X lines [PS]

A. Wik
On Wed, 9 Dec 2020 at 19:35, Gabriele F <[hidden email]> wrote:

>
> On 07/12/2020 13.59, A. Wik wrote:
> > Now, I want to do the following
> > :redir @m
> > :g/future.*ref.*\n.*\n
> > :redir END
> >
> > Alternatively, instead of redir, I can use [...]/y M at the end of the
> > :g command.
> >
> > Alas, :g includes only the line matching "future.*ref".  I want to
> > capture the whole match.  Is there a way to do that?
>
> It would seem that what's wrong with the first command is simply that
> :p, which is the command used by default by :g, by itself prints only
> *one* line. If you instead explicitly use :p {count}, e.g.
> ":g/future.*ref.*\n.*\n/p 3", it seems to work.

Yes, but I want to collect the text that was *matched* by the pattern,
so, with ":g/future.*ref.*\n.*\n", I want the "future" until the end
of the next line.  Actually, what I want is the whole line containing
the match, as well as the whole of the next line, but that is a simple
matter of adding a "^.*".

> But, was this what you meant to ask in the first question, or an
> additional issue?

An additional issue.

> «trying to match a couple (maybe more later) of words occurring within 3
> lines of each other in any order» seems to mean more what Tim helped you
> with...?

That was the question he helped me with.  I ran into the additional issue later.

-aw

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/vim_use/CALPW7mSfiADH56mfWMguSo94qWJX7a55S%2B8FH-BNMoEy%2BgHp3Q%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Matching words within X lines [PS]

Gabriele Fava
On 10/12/2020 16.29, A. Wik wrote:

> On Wed, 9 Dec 2020 at 19:35, Gabriele F <[hidden email]> wrote:
>> On 07/12/2020 13.59, A. Wik wrote:
>>> Alas, :g includes only the line matching "future.*ref".  I want to
>>> capture the whole match.  Is there a way to do that?
>> It would seem that what's wrong with the first command is simply that
>> :p, which is the command used by default by :g, by itself prints only
>> *one* line. If you instead explicitly use :p {count}, e.g.
>> ":g/future.*ref.*\n.*\n/p 3", it seems to work.
> Yes, but I want to collect the text that was *matched* by the pattern,
> so, with ":g/future.*ref.*\n.*\n", I want the "future" until the end
> of the next line.  Actually, what I want is the whole line containing
> the match, as well as the whole of the next line, but that is a simple
> matter of adding a "^.*".

Well if you want only from "future" I don't know, but if instead you
want "the whole line containing
the match, as well as the whole of the next line"
":g/future.*ref.*\n.*\n/p 2" seems to give that result, and only if
there is a match (yes, I put "p 3" by mistake in the other mail).
Of course inelegant and inflexible, I don't know if there are better ways

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/vim_use/024229c8-b4e7-6337-89e7-1dbe92567b81%40tiscali.it.
Reply | Threaded
Open this post in threaded view
|

Re: Matching words within X lines [PS]

A. Wik
On Thu, 10 Dec 2020 at 16:32, Gabriele F <[hidden email]> wrote:
>
> Well if you want only from "future" I don't know, but if instead you
> want "the whole line containing
> the match, as well as the whole of the next line"
> ":g/future.*ref.*\n.*\n/p 2" seems to give that result, and only if
> there is a match (yes, I put "p 3" by mistake in the other mail).
> Of course inelegant and inflexible, I don't know if there are better ways

You are right.  And in this particular case, the regex can be
simplified to "/future.*ref/".

-aw

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/vim_use/CALPW7mQp_p%3DpWT0yx95vMGdM3N-LqSMxJ3cxJ%2Bx20HqK41OEfQ%40mail.gmail.com.
Reply | Threaded
Open this post in threaded view
|

Re: Matching words within X lines [PS]

Gabriele Fava
On 10/12/2020 17.56, A. Wik wrote:
> You are right.  And in this particular case, the regex can be
> simplified to "/future.*ref/".

Sure

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To view this discussion on the web visit https://groups.google.com/d/msgid/vim_use/4f8c9004-8b17-243e-d0d7-a1e6b0d73bfa%40tiscali.it.