3

In the next search on Vim I would like to ignore the case of the first letter:

/[tlcp]omo

I'd like to know how the case can be ignored for only the first letter of the search pattern.

Vim has the following options to ignore the case in the search pattern:

:set ignorecase
:set smartcase [ignore case if no uppercase in search]

or use \c it at any position in the search pattern:

/hello\c => [find hello and HELLO]

But all of these options ignore the case in the entire pattern, not in part.

One option to ignore the case of a single letter in the search pattern is, using the [] collection of regular expression, to specifically capitalize each letter:

/[tTlLcCpP]omo

But, is there any way to ignore the case in a part of the search pattern without having to specify each and every upper and lower case character using regular expression?

robertspierre
  • 3,218
  • 2
  • 31
  • 46
Carlos A. Gómez
  • 362
  • 4
  • 12
  • 1
    I would imagine that https://stackoverflow.com/q/2287440/2191572 has the answer you are looking for and from my quick overview it does not appear possible to achieve your edge-case request using Vim. – MonkeyZeus Feb 12 '20 at 17:48
  • @MonkeyZeus But the answer to my question is not in that entry. There they answer to ignore the case in the whole search pattern, and my question is how to do it for a part. – Carlos A. Gómez Feb 12 '20 at 17:50
  • 1
    I'm unfamiliar with `VIM`, but would the inline modifiers work as per [this](https://regex101.com/r/iX1qAt/2)? – JvdV Feb 12 '20 at 17:53
  • @JvdV it doesn't work in _Vim_. Thanks :) – Carlos A. Gómez Feb 12 '20 at 17:56
  • 1
    What would happen if you used `\c` followed by `\C` per https://stackoverflow.com/a/2287449/2191572? Would it act like the inline modifier that @JvdV mentioned? – MonkeyZeus Feb 12 '20 at 17:59
  • @MonkeyZeus It doesn't work either. It doesn't matter where you put the modifier `\c` that acts for the entire search pattern. – Carlos A. Gómez Feb 12 '20 at 18:01
  • 1
    @sergio OP explicitly mentioned they wish to avoid writing out all lowercase chars plus their uppercase variant. – MonkeyZeus Feb 12 '20 at 18:05
  • 1
    Maybe there is a way within `VIM` to change 1st char into `Ucase` or `Lcase` inline. Feeding this to your `RegEx`? – JvdV Feb 12 '20 at 18:12
  • 1
    Interesting question, been looking for an answer myself for the past 30min, but there does not seem to be any. Vim always seems to prefer `\c` over `\C` is what I found out :p – Sander Vanhove Feb 12 '20 at 18:23
  • @JvdV You can use `\u` (or `\l`) to convert to upper (or lower) case the next character within a substitution, but it only applies in the replacement pattern, not in the search pattern. In the search pattern, `\u` (or `\l`) is equivalent to searching for any uppercase (or lowercase) character. – Carlos A. Gómez Feb 12 '20 at 18:23
  • 1
    @SanderVanhove In [this link (in spanish)](https://es.stackoverflow.com/a/328901/12809), a colleague comments something similar. There is no possible solution in Vim. – Carlos A. Gómez Feb 12 '20 at 18:26
  • @SanderVanhove I'm trying but it takes me to the end of the file. – Carlos A. Gómez Feb 12 '20 at 18:37
  • 1
    Yeah I'm sorry, it did not work as intended. – Sander Vanhove Feb 12 '20 at 19:08

2 Answers2

2

In general, this isn't possible in Vim. The /\c and /\C regexp modifiers unfortunately turn the whole pattern into case (in-)sensitive matching, regardless of where they are placed. (Introducing a new set of modifiers that only work from that position onwards would in my opinion be the best solution.)

Most people usually get around this by using lower/uppercase collections for the insensitive parts, /like [tT][hH][iI][sS]/.

You could also go the opposite route and instead force certain characters to a case (using /\l for lowercase and /\u for uppercase), /\c\%(\l\l\l\l\&like\) this/.

Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
  • [In this link (in spanish)](https://es.stackoverflow.com/a/328901/12809), a colleague comments something similar. **There is no possible solution in Vim**. – Carlos A. Gómez Mar 05 '20 at 16:35
0

My CmdlineSpecialEdits plugin has (among many others) a CTRL-G c mapping that converts a pattern in the search command-line in such a way that those alphabetic characters between \c...\C become case-insensive matches while the rest remains case-sensitive. In other words, it converts the pattern as if \c and \C would only apply to following atoms, and not the entire pattern.

Example

/My \cfoo\C is \cbad!/

becomes

/My [fF][oO][oO] is [bB][aA][dD]!/

or alternatively

/\c\%(\u\&M\)\%(\l\&y\) foo\%(\l\{2}\&is\)  bad!/
Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324