Friday, February 26, 2016

Re: Search for line containing stringB, not preceded by a line containing stringA

On Friday, February 26, 2016 at 9:50:50 AM UTC-6, Paul wrote:
> On Wednesday, February 24, 2016 at 3:01:24 PM UTC-5, Ben Fritz wrote:
> > On Wednesday, February 24, 2016 at 12:00:22 PM UTC-6, Paul wrote:
> > > I have a text file and I would like to compose a regular expression
> > > that matches lines containing stringB but not preceded by a line
> > > containing string A. I thought one of these might do it:
> > >
> > > \(stringA.*\n\)\@<!.*stringB
> > > \(stringA.*\n\)\@<!\(.*stringB\)
> > >
> > > The \@<! was *intended* to ensure a non-match with stringA in the
> > > preceding line. However, they highlight the same lines that are
> > > highlighted by the opposite regular expressions:
> > >
> > > \(stringA.*\n\)\@<=.*stringB
> > > \(stringA.*\n\)\@<=\(.*stringB\)
> > >
> > > With a little pondering, it is obvious why. The first .* matches any
> > > set of characters, so even if stringA exists in the preceding line,
> > > you can always find some portion of the line that doesn't match
> > > \(stringA.*\n\).
> > >
> > > Is there a way to achieve the search described in above?
> >
> > Move the newline outside of your negative look-behind, then start the match using \zs after the newline if you only want to match the 2nd line.
> >
> > Make it work on the 1st line as well by temporarily inserting a blank line at the top, or checking it manually, if needed.
> >
> > Here's what I mean, if my description isn't clear: \(stringA.*\)\@<!\n\zs.*stringB
>
> Thanks, Ben. The problem isn't whether the 1st and/or the 2nd of the two lines are matched. It's whether I can even locate lines containing stringB *only* when the preceding line does not contain stringA. Currently, all expressions locate cases of stringB regardless of whether the preceding contains stringA. The text file I use is:
>
> asldkfjals stringA asldkjf
> asldkfjals stringB asldkjf
>
> asldkfjals stringX asldkjf
> asldkfjals stringB asldkjf
>
> asldkfjals stringA asldkjf
> asldkfjals stringB asldkjf
>
> asldkfjals stringX asldkjf
> asldkfjals stringB asldkjf

Did you try the pattern I sent? Works for me on your test data. The key was to move the \n out of the lookbehind to make sure you're matching line boundaries.

The part about whether the 1st or 2nd line matches was just the \zs to exclude the newline from the matched text itself while forcing it to be present just before the match.

--
--
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 vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments: