【问题标题】:vim syntax: match only when between other matchesvim 语法:仅在其他匹配之间匹配
【发布时间】:2016-01-02 08:55:22
【问题描述】:

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

[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

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

这是怎么做到的?

【问题讨论】:

    标签: vim vim-syntax-highlighting


    【解决方案1】:

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

    [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'
    

    【讨论】:

    • 这几乎可以完美地工作,但是有些行的突出显示不适用于文件和行号。 here 就是这样几行。时间和等级高亮很好。
    • 我注意到的是,这些行都有一个数字,后面紧跟一个右括号。我没有看到突出显示确实有效的任何此类行。
    • 我明白了。它实际上是右括号紧跟空格,然后紧跟大写字母。
    • @ewok 我更新了我的答案,包括对语法匹配如何工作的解释。我现在没有时间研究你的新格式,但希望解释能帮助你解决这个问题。
    • @ewok 我再次更新了答案,并评论了为什么我使用包含匹配将某些事物组合在一起。
    猜你喜欢
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多