vim 语法:仅在其他匹配项之间匹配 [英] vim syntax: match only when between other matches

查看:22
本文介绍了vim 语法:仅在其他匹配项之间匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为我的日志文件创建一个语法文件.它们采用以下格式:

I am trying to create a syntax file for my logfiles. They take the format:

[time] LEVEL filepath:line - message

我的语法文件是这样的:

My syntax file looks like this:

:syn region logTime start=+^\[+ end=+\] +me=e-1
:syn keyword logCritical CRITICAL skipwhite nextgroup=logFile
:syn keyword logError ERROR skipwhite nextgroup=logFile
:syn keyword logWarn WARN skipwhite nextgroup=logFile
:syn keyword logInfo INFO skipwhite nextgroup=logFile
:syn keyword logDebug DEBUG skipwhite nextgroup=logFile
:syn match logFile " \S\+:" contained nextgroup=logLineNumber
:syn match logLineNumber "\d\+" contained

我遇到的问题是,如果消息中出现字符串 ERRORDEBUG 或某些内容,它会突出显示.但我不想这样.我希望它只在关键字在时间之后和文件路径之前立即出现时才会突出显示.

The issue I have is that if the string ERROR or DEBUG or something occurs within the message, it gets highlighted. But I don't want it to. I want it so that the keywords only get highlighted if they fall immediately after the time and immediately before the filepath.

这是怎么做到的?

推荐答案

使用如下所示的测试文件:

Using a test file that looks like this:

[01:23:45] ERROR /foo/bar:42 - this is a log message
[01:23:45] ERROR /foo/bar:42 - this is a ERROR log message
[01:23:45] CRITICAL /foo/bar:42 - this is a log message
[01:23:45] CRITICAL /foo/bar:42 - this is a CRITICAL log message

这个语法文件对我有用,不会在消息部分突出显示那些关键字.

This syntax file works for me and does not highlight those keywords in the message portion.

" Match the beginning of a log entry. This match is a superset which
" contains other matches (those named in the "contains") parameter.
"
"     ^                   Beginning of line
"     \[                  Opening square bracket of timestamp
"         [^\[\]]\+       A class that matches anything that isn't '[' or ']'
"                             Inside a class, ^ means "not"
"                             So this matches 1 or more non-bracket characters
"                             (in other words, the timestamp itself)
"                             The \+ following the class means "1 or more of these"
"     \]                  Closing square bracket of timestamp
"     \s\+                Whitespace character (1 or more)
"     [A-Z]\+             Uppercase letter (1 or more)
"
" So, this matches the timestamp and the entry type (ERROR, CRITICAL...)
"
syn match logBeginning "^\[[^\[\]]\+\]\s\+[A-Z]\+" contains=logTime,logCritical,logError,logWarn,logInfo,logDebug

" A region that will match the timestamp. It starts with a bracket and
" ends with a bracket. "contained" means that it is expected to be contained
" inside another match (and above, logBeginning notes that it contains logTime).
" The "me" parameter e-1 means that the syntax match will be offset by 1 character
" at the end. This is usually done when the highlighting goes a character too far.
syn region logTime start=+^\[+ end=+\] +me=e-1 contained

" A list of keywords that define which types we expect (ERROR, WARN, etc.)
" These are all marked contained because they are a subset of the first
" match rule, logBeginning.
syn keyword logCritical CRITICAL contained
syn keyword logError ERROR contained
syn keyword logWarn WARN contained
syn keyword logInfo INFO contained
syn keyword logDebug DEBUG contained

" Now that we have taken care of the timestamp and log type we move on
" to the filename and the line number. This match will catch both of them.
"
" \S\+         NOT whitespace (1 or more) - matches the filename
" :            Matches a literal colon character
" \d\+         Digit (1 or more) - matches the line number
syn match logFileAndNumber " \S\+:\d\+" contains=logFile,logLineNumber

" This will match only the log filename so we can highlight it differently
" than the line number.
syn match logFile " \S\+:" contained

" Match only the line number.
syn match logLineNumber "\d\+" contained

您可能会好奇为什么我不使用各种匹配,而是使用包含匹配.那是因为像 \d\+ 这样的一些匹配太通用了,无法匹配行中的任何地方并且是正确的 - 使用包含的匹配,它们可以组合成更可能正确的模式.在此语法文件的较早版本中,某些示例行是错误的,因为例如,如果ERROR"出现在该行后面的日志条目文本中,则会突出显示.但是在此定义中,这些关键字仅在它们位于仅显示在行首的时间戳旁边时才匹配.因此,容器是一种更精确匹配的方式,同时还可以控制正则表达式的长度和复杂性.

You might be curious why instead of just using various matches, I used contained matches. That's because some matches like \d\+ are too generic to match anywhere in the line and be right - using contained matches they can be grouped together into patterns that are more likely to be correct. In an earlier revision of this syntax file, some example lines were wrong because for instance if "ERROR" showed up in the log entry text later in the line, it would be highlighted. But in this definition, those keywords only match if they are next to a timestamp which shows up at the beginning of the line only. So the containers are a way to match more precisely but also keep the regexes under control as far as length and complexity.

更新:根据您提供的示例行(如下所述),我改进了上面第一行的正则表达式,在我的测试中,它现在可以正常工作了.

Update: Based on the example lines you provided (noted below), I have improved the regex on the first line above and in my testing, it works properly now.

[2015-10-05 13:02:27,619] ERROR /home/admusr/autobot/WebManager/wm/operators.py:2371 - Failed to fix py rpc info: [Errno 2] No such file or directory: '/opt/.djangoserverinfo'
[2015-10-05 13:02:13,147] ERROR /home/admusr/autobot/WebManager/wm/operators.py:3223 - Failed to get field "{'_labkeys': ['NTP Server'], 'varname': 'NTP Server', 'displaygroup': 'Lab Info'}" value from lab info: [Errno 111] Connection refused
[2015-10-05 13:02:38,012] ERROR /home/admusr/autobot/WebManager/wm/operators.py:3838 - Failed to add py rpc info: [Errno 2] No such file or directory: '/opt/.djangoserverinfo'
[2015-10-05 12:39:22,835] DEBUG /home/admusr/autobot/WebManager/wm/operators.py:749 - no last results get: [Errno 2] No such file or directory: u'/home/admusr/autobot/admin/branches/Wireless_12.2.0_ewortzman/.lastresults'

这篇关于vim 语法:仅在其他匹配项之间匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆