1

Consider the following test String:

County,Age,Age_group,Gender,Jurisdiction,Travel_related,Origin,EDvisit,Hospitalized,Died,Case_,Contact,Case1,EventDate,ChartDate,ObjectId

If use the following regex to search:

\v((.{-},){9})\zsDied

I get the expected result of having the word Died in the test String be matched.

If I use the following regex instead to search:

\v((.{-},){9})\zsEvent

I also get a match. This is confusing to me, as the String Event is not immediately following the String matched by the zero width pattern: \v((.{-},){9})\zs

If I then use the following:

\vDied,\zsEvent

\vDied,\zsCase

The first one does not match and the second one does match, both as I would expect. If somebody here could explain this inconsistency in behavior, I would greatly appreciate it.

I ran these tests on gvim 8.2 on Linux.

1

2 Answers 2

4

Removing the \zs and looking the highlighting makes it pretty clear what is happening; /\v((.{-},){9})Event. This regex spells "(match anything non-greedily, followed by a comma) 9 times, followed by Event."

There are two problems here:

  1. Although it is not greedy, .{-} may also match comma, whenever necessary to form a full match.

  2. Even if 1 were not true, you don't specify an anchor like ^, so the match may occur anywhere. There are certainly 9 Word-comma strings before Event.

1
  • Thank you very much. After reading over your observations here is the pattern that I came up with to basically do what I want: /\v^([^,]{-},){9}\zs. This basically is going to skip past the first 9 comma delimited columns
    – Sergio
    Sep 25, 2020 at 3:45
2

String Event is not immediately following the String matched by the zero width pattern: /\v((.{-},){9})\zs.

It actually is. That pattern will match at least 9 commas separating fields, but it will actually match them later in the line as well. So while you won't be able to match Hospitalized, EDvisit, Origin or the other fields that precede Died. On the other hand, it will match Case_, Contact, Case1, EventDate and the other fields that come after Died.

There are two issues preventing the regex to match only the tenth field (the one preceded by exactly 9 commas.) The first issue is that . will match any character, including a comma. You can fix that by using [^,] instead of .. Second, you don't have an anchor to the start of the string. You can easily add one with ^.

Result: /\v^(([^,]{-},){9})\zsDied. This will work with the field Died, but not with any other field. You can actually simplify this regex, since you don't need a pair of parents. You don't need the {-} non-greedy repeat anymore, since [^,] will not match the commas. Simplified regex: /\v^([^,]*,){9}\zsDied.

Hopefully this also makes it clear why /\vDied,\zsEvent won't match (Event doesn't follow Died,), while /\vDied,\zsCase does. It doesn't really have anything to do with the \zs itself.

1
  • 1
    Thank you for your answer as well, and for further simplifying what I was ultimately trying to do
    – Sergio
    Sep 25, 2020 at 3:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.