1

I've tried to debug an indent function i've written, and came over this strange behaviour. Here I try to detect some LateX tags (debug output):

>echo previous
\label{ch10.1}
>echo previous =~ "\\label"
1

This looks fine. Now i try to do the same thing with the \begin tag:

>echo previous
\begin{uxlist}
>echo previous =~ "\\begin"
0

It somehow works with \\\\:

>echo previous 
\begin{uxlist}
>echo previous =~ "\\\\begin"
1

Which makes no sense at all for me. Is this expected behaviour? If yes I would be rather glad for an explanation.

Thanks in advance

Update

I solved it by replacing doublequotes with singlequotes. But it is still strange for example this:

>echo previous
  \end{itemize}
>previous =~ "\\item" 
1
>previous =~ "\\end"
0

it looks like \\end is somehow interpreted as \e (Escape) which can not be found. That would mean I had to esacpe each backslash 2 times, which is why it works with 4 backslashes. But as far as I know, that shouldn't be needed?

1 Answer 1

3

The documentation says (scroll down to expr5 and expr6):

The "=~" and "!~" operators match the lefthand argument with the righthand argument, which is used as a pattern. See pattern for what a pattern is. This matching is always done like 'magic' was set and 'cpoptions' is empty, no matter what the actual value of 'magic' or 'cpoptions' is. This makes scripts portable. To avoid backslashes in the regexp pattern to be doubled, use a single-quote string, see literal-string.

So this is intended behaviour.

The confusion is caused by the fact that there is no special syntax for regular expressions in Vim's grammar of expressions (like, say, /regex/ is some languages). This means that Vim reuses its syntax for string literals, which enforces its own set of rules on top of syntax of regular expressions.

6
  • Thank you very much. So this is inconsistent with h: expr-quote where the double backslash is not mentioned. You answered my question without doubt, but if anyone know why it is implemented that way, I would love to hear it.
    – B.G.
    Oct 2, 2017 at 10:07
  • 1
    When you use "...", you need to escape ` (and other special characters). Thus, "\\begin"` becomes '\begin', and as a regex, you now start with the \b atom which matches any <bs> characters. Thus it won't match the string \begin{...}. However, \l will match lower case characters, and so "\\label" as a regex becomes \label which is the same as [a-z]abel. Oct 2, 2017 at 10:24
  • 1
    @KarlYngveLervåg so a doublequoted string gets throught the string processor, and then througth the regex processor or something like that? Even when using =~ ?
    – B.G.
    Oct 2, 2017 at 10:45
  • 1
    @DoktorOSwaldo, your guess is correct, see my edit.
    – xaizek
    Oct 2, 2017 at 11:45
  • 1
    Note that this is also why it is strongly recommended to always use single quoted strings if possible. Linters (e.g. vint) will warn about unnecessary use of double quoted strings. Oct 2, 2017 at 13:14

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.