vim 语法:仅在其他匹配项之间匹配
vim syntax: match only when between other matches
我正在尝试为我的日志文件创建语法文件。它们采用以下格式:
[time] LEVEL filepath:line - message
我的语法文件如下所示:
: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
我遇到的问题是,如果消息中出现字符串 ERROR
或 DEBUG
或其他内容,它会突出显示。但我不想这样。我想要这样,只有当关键字紧跟在时间之后和文件路径之前时,它们才会突出显示。
这是怎么做到的?
使用如下所示的测试文件:
[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
这个语法文件适合我,不会突出显示消息部分中的那些关键字。
" 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" 出现在该行后面的日志条目文本中,它将被突出显示。但在这个定义中,这些关键字只有在紧挨着出现在行首的时间戳时才会匹配。因此,容器是一种更精确匹配的方式,但也可以控制正则表达式的长度和复杂性。
更新: 根据您提供的示例行(如下所示),我改进了上面第一行的正则表达式,在我的测试中,它现在可以正常工作。
[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'
我正在尝试为我的日志文件创建语法文件。它们采用以下格式:
[time] LEVEL filepath:line - message
我的语法文件如下所示:
: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
我遇到的问题是,如果消息中出现字符串 ERROR
或 DEBUG
或其他内容,它会突出显示。但我不想这样。我想要这样,只有当关键字紧跟在时间之后和文件路径之前时,它们才会突出显示。
这是怎么做到的?
使用如下所示的测试文件:
[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
这个语法文件适合我,不会突出显示消息部分中的那些关键字。
" 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" 出现在该行后面的日志条目文本中,它将被突出显示。但在这个定义中,这些关键字只有在紧挨着出现在行首的时间戳时才会匹配。因此,容器是一种更精确匹配的方式,但也可以控制正则表达式的长度和复杂性。
更新: 根据您提供的示例行(如下所示),我改进了上面第一行的正则表达式,在我的测试中,它现在可以正常工作。
[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'