Friday, February 26, 2016

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

On Friday, February 26, 2016 at 12:26:21 PM UTC-5, Ben Fritz wrote:
> 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.

Actually, I thought I did, but it was in the middle of the night in my
neck of the woods, when the fire alarm system malfunctioned. I was in
zombie mode, and likely just copy & pasted my own regular expressions
instead. Your expression works as you said. Thanks.

I am a bit confused as to *why* it works. If my guess as to why my
original expressions failed is correct, it should apply to your
expression as well.

--
--
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: