2

I am looking for a way to match any line in a csv file that contains an identifier (e.g. OfficeLocation) and then, later on, the same identifier in all caps. A line to be matched might look like:

OfficeLocation,5,1783,DB-OFFICELOCATION,72,56

My first thought was to attempt to capitalize a backreference as follows:

/\v(\w+),([^,]+,){2}(\U\1)

The above does not work, of course, because in a search \U matches any uppercase character, rather than coercing the match to uppercase as it would in a substitution. Is there a way to express my intent in vim regular expressions?

1
2

This is not a direct solution to matching the capitalized version of a backreference, as I don't believe it's possible to do so with Vim regexps... But one thing you can do is to use a zero-width match for a series of capitalized letters and a case-insensitive match for the backreference in the same place.

You can use the \@= operator for a zero-width match of the preceding token. Here you are using \v for verymagic mode, so you simply use @= for that operator.

And you can use \c at the start of your match to make it a case-insensitive match.

In your case, you could use something like:

/\c\v^(\w+),([^,]+,){2}([[:upper:]-]+,)@=DB-\1,

Breaking it down:

  • \c: Case insensitive.
  • \v: Very magic.
  • ^(\w+),: Match the first word of the line and store it in capture group \1. Skip the comma delimiter following the word.
  • ([^,]+,){2}: Skip the next two comma-separated groups.
  • ([[:upper:]-]+,)@=: Match a field completely made up of uppercase letters and possibly dashes, followed by a comma. Make it a zero width match, through the @= part.
  • DB-\1,: Match the contents of capture group \1, following the DB- prefix, followed by a final comma. Since this is following the @= operator, this will match the same region matched by the [[:upper:]-]+, pattern, so it will make sure that region matches both the backreference and the character class that includes only uppercase characters.

You can test this regex with variations of the capitalization of the fourth field, both in the DB- prefix and in the backreference, and you'll see it only matches when the whole field is capitalized as intended.

1
  • 1
    Thanks, I hadn't considered matching it twice using the zero-width operator. That's a neat little trick.
    – mcwayliffe
    Dec 2 at 15:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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