regexvimneovim

vim regex search for a char Not Keyword and Not Space followed by a Keyword


I need to match couples of chars as

e.g. "!b", "$a", "$ ", ...

It would be trivial...but it seems that "[^\s\k]" is not accepted in vim regex and/or doesn't work...

p.s. I need \k since I want to be compatible with what is set in vim.opt.iskeyword. And I need \s since I would include any non visible char, not only space " ".

(I use NeoVim but is the same in Vim)


Solution

  • The only \<char> pairs accepted in a collection are listed a little bit further down :help /[, under :help /\]:

    - The following translations are accepted when the 'l' flag is not
      included in 'cpoptions':
        \e  <Esc>
        \t  <Tab>
        \r  <CR>    (NOT end-of-line!)
        \b  <BS>
        \n  line break, see above |/[\n]|
        \d123   decimal number of character
        \o40    octal number of character up to 0o377
        \x20    hexadecimal number of character up to 0xff
        \u20AC  hex. number of multibyte character up to 0xffff
        \U1234  hex. number of multibyte character up to 0xffffffff
    

    so [^\k\s] can't be expected to work.

    What works, though, is "character class expressions", which are listed a couple of screens up from the list above:

    [:alnum:]      [:alnum:]       isalnum    ASCII letters and digits
    [:alpha:]      [:alpha:]       isalpha    ASCII letters
    [:blank:]      [:blank:]       space and tab
    [:cntrl:]      [:cntrl:]       iscntrl    ASCII control characters
    [:digit:]      [:digit:]       decimal digits '0' to '9'
    [:graph:]      [:graph:]       isgraph    ASCII printable characters excluding space
    [:lower:]      [:lower:] (1)   lowercase letters (all letters when 'ignorecase' is used)
    [:print:]      [:print:] (2)   printable characters including space
    [:punct:]      [:punct:]       ispunct    ASCII punctuation characters
    [:space:]      [:space:]       whitespace characters: space, tab, CR, NL, vertical tab, form feed
    [:upper:]      [:upper:] (3)   uppercase letters (all letters when 'ignorecase' is used)
    [:xdigit:]     [:xdigit:]      hexadecimal digits: 0-9, a-f, A-F
    [:return:]     [:return:]      the <CR> character
    [:tab:]        [:tab:]         the <Tab> character
    [:escape:]     [:escape:]      the <Esc> character
    [:backspace:]  [:backspace:]   the <BS> character
    [:ident:]      [:ident:]       identifier character (same as "\i")
    [:keyword:]    [:keyword:]     keyword character (same as "\k")
    [:fname:]      [:fname:]       file name character (same as "\f")
    

    In this specific case, the correct pattern would be:

    /[^[:keyword:][:blank:]]\(\k\|\s\)
    

    where…