Paul T.
Paul T.

Reputation: 326

Vim regex to find numbers that are not part of other words

I'm writing a syntax file for Vim and am looking for a regex to match (so I can highlight) floating point and integer numbers, but not numbers that appear in words, like variable or function names.

Further the language doesn't like floats that end on a decimal point like 5. or 3.e9. Not matching such numbers is acceptable. Matching such numbers separately to mark as Error would also be acceptable.

For instance if I have:

var1 = 3.2e-9
var2 = atan2(5.3, 7e+02)
var3 = -6

Then only 3.2e-9, 5.3, 7e+02, and -6 should be found. It's ok to do it in multiple steps.

For instance this:

[-+]\=\d

gets integers, but it would also match the 1 in var1.

These two expressions:

[-+]\=\d\+\(\.\d\+\)\=\([eE][-+]\=\d\+\)\=
[-+]\=\.\d\+\([eE][-+]\=\d\+\)\=

match both floating point numbers with or without scientific notation and integers. Using these two, we miss miss 5. and 3.e9. (the second is necessary to match numbers that start with a decimal point like .42.

Can I tell the regex about preceding characters?

This comes to mind:

\A[+-]\=\d\+

It would ignore the 1 in var1. But it would also match (5, causing the parentheses to highlight.

My understanding of syntax files has me writing:

syn match myNumber '[-+]\=\d\+\(\.\d\+\)\=\([eE][-+]\=\d\+\)\='
syn match myNumber '[-+]\=\.\d\+\([eE][-+]\=\d\+\)\='

let b:current_syntax = "myLang"

hi def link myNumber Number

Is there a was to do syntax highlighting without regex?

As pointed out in a comment there may be problems with expressions like 2+3. How can I tell that this is not a word?

So what is the best number matching method?

Upvotes: 2

Views: 1040

Answers (1)

Ben
Ben

Reputation: 8905

You probably want one of these methods:

Using the beginning-of-word anchor \< (:help /\<)

Using a negative zero-width look-behind: \@<! (:help /\@

Forcing specific sets characters to occur before the digit, but not including them in the match, using \zs (:help /\zs). For example, for only whitespace, newlines, or parentheses you could use \(\_s\|[()]\)\zs[+-]\=\d\+

Upvotes: 1

Related Questions