VSCode任务tasks.json中的问题匹配器problemMatcher的问题匹配模式ProblemPattern详解

本文主要是介绍VSCode任务tasks.json中的问题匹配器problemMatcher的问题匹配模式ProblemPattern详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

☞ ░ 前往老猿Python博客 ░ https://blog.csdn.net/LaoYuanPython

一、简介

在 VS Code 中,tasks.json 文件中的 problemMatcher 字段用于定义如何解析任务输出中的问题(错误、警告等)。

problemMatcher有三种配置方式,具体可参考《VSCode中的任务什么情况下需要配置多个问题匹配器problemMatcher?多个问题匹配器之间的关系是什么?》的介绍。

本文要介绍的是problemMatcher为一个ProblemMatcher的JSON对象时其下的子对象pattern,pattern用于匹配任务执行时输出的信息,如编译任务输出的告警和错误信息,对符合pattern指定匹配规则的信息则纳入problemMatcher处理。

二、测试的C++代码文件样例

为了测试vscode的问题匹配,下面是一个故意存在多处错误的hello.cpp文件的代码,注意就是一个完整的cpp文件,不存在单独的头文件和其他外部文件:

#include <stdio.h>
#include <stdlib.h>
#include "myhead.h"int main()
{int loop;int i,j;printf("j=%s\n",j);for(loop=0;loop<5;loop++)printf("hello,world!%d\n",i);i++;hell("");    }

大家看得出来几处问题代码吗?

三、问题匹配器中的模式pattern介绍

3.1、vscode中pattern的定义

pattern在vscode中 的定义如下:

pattern: string | ProblemPattern | ProblemPattern[]

关于这个定义,vscode官方文档中有如下说明:The name of a predefined problem pattern, the inline definition of a problem pattern or an array of problem patterns to match problems spread over multiple lines,结合上述定义和文字说明可知,pattern可以为字符串、ProblemPattern类型对象和ProblemPattern数组:

  1. pattern为字符串的情况,vscode官方说是预定义的匹配模式,老猿查阅了很多资料,也许是统信下的vscode版本1.81.0太低,也许是没找对方法,在vscode1.81.0中反复测试也没有测试通过;
  2. pattern 为 ProblemPattern类型的对象时,包含有多个子对象,在接下来的3.2节中详细介绍其相关信息;
  3. pattern 为 ProblemPattern类型的数组时,表明其所在的问题匹配器的匹配模式可以有多种,这些匹配模式按照配置中的先后顺序逐一与输出信息匹配,如果都匹配成功,则整个问题匹配成功,否则就是未匹配,即多个匹配模式是与的关系,这个与问题匹配器problemMatcher多个之间是或的关系是不同的。查阅了vscode的官方文档,这种模式数组是用于匹配多行。不过关于此模式老猿一直未能测试成功,3.3节再介绍测试情况。

3.2、ProblemPattern类型介绍

3.2.1、ProblemPattern类的定义

以下是vscode官方文档中关于ProblemPattern类的定义:

interface ProblemPattern {/** The regular expression to find a problem in the console output of an* executed task.*/regexp: string; /*** Whether the pattern matches a problem for the whole file or for a location* inside a file.* Defaults to "location".  */kind?: 'file' | 'location';/*** The match group index of the filename.  */file: number;/*** The match group index of the problem's location. Valid location* patterns are: (line), (line,column) and (startLine,startColumn,endLine,endColumn).* If omitted the line and column proper从上面官方文档的介绍可以知道,ProblemPattern包含多个子元素,下面分每个子元素展开介绍。从以上定义的英文注释能理解大部分定义要素的含义,但有些光理解注释的字面意思还不够,老猿结合测试情况对这些ties are used.   */location?: number;/**   * The match group index of the problem's line in the source file.* Can only be omitted if location is specified.   */line?: number;/**The match group index of the problem's column in the source file.   */column?: number;/**   * The match group index of the problem's end line in the source file.* Defaults to undefined. No end line is captured.   */endLine?: number;/**   * The match group index of the problem's end column in the source file.** Defaults to undefined. No end column is captured.   */endColumn?: number;/*** The match group index of the problem's severity.* Defaults to undefined. In this case the problem matcher's severity* is used.  */severity?: number;/*** The match group index of the problem's code.* Defaults to undefined. No code is captured.*/code?: number;/*** The match group index of the message. Defaults to 0. */message: number;/*** Specifies if the last pattern in a multi line problem matcher should* loop as long as it does match a line consequently. Only valid on the* last problem pattern in a multi line problem matcher.   */loop?: boolean;
}
3.2.2 ProblemPattern类型的介绍

从上面官方文档的介绍可以知道,ProblemPattern包含多个子元素,从以上定义的英文注释能理解大部分定义要素的含义,但有些光理解注释的字面意思还不够,老猿结合测试情况对这下面分每个子元素展开介绍。

3.2.2.1、 regexp
3.2.2.1.1、regexp概述

regexp对应为匹配输出问题信息的正则表达式,正则表达式使用的元字符与Python的re模块基本一致,如元字符包括:“.*?[]{}[]\+-^$”等,转义符为"\",同时支持转义符定义的特殊序列以及组匹配模式,支持通过组序号方式来访问匹配内容,需要注意转义符在字符串中需要使用双斜杠。关于Python正则表达式的有关介绍请参考老猿在CSDN的博文专栏《Python 支撑正则表达式处理的re模块》。

3.2.2.1.2、regexp正则表达式中常用的元字符及含义

regexp正则表达式中部分常用元字符及其含义:

  • ^:匹配字符串的开头
  • \s*:匹配零个或多个空格字符
  • (.*):匹配任意字符,零个或多个 字符
  • (\d+):匹配一个或多个数字字符
  • \s+:匹配一个或多个分隔字符 (如空格、回车、tab等)
  • (子正则表达式):用于将指定正则匹配的内容进行分组

案例:"^(.*):(\\d+):(\\d+):\\s+(error):\\s+(.*)$"
这个正则语句匹配如下类似的错误信息:hello.cpp:3:10: error: myhead.h: 没有那个文件或目录,其中文件名的匹配组号为1、行号匹配组号位2、列号的匹配组号为3,匹配的问题级别信息“error”的匹配组号为4,具体错误信息匹配组号为5

3.2.2.2、kind

指问题匹配时匹配到问题具体的行列位置还是只需要匹配到文件,有2个取值,一个是“file”,表示只需要匹配到文件,另一个是“location”,匹配到行列指定的具体位置,缺省值是“location”。

我们通过案例来看看问题面板输出的不同,以上面hello.cpp的爆粗信息:hello.cpp:3:10: fatal error: myhead.h: 没有那个文件或目录为例:

  1. 设置为“location”,问题面板中输出信息文件那栏输出了文件名、行号、列号,如图:
    在这里插入图片描述
    注意,零两个问题不是问题匹配器problem_1输出的,而是扩展组件C++智能感知输出的。
  2. 设置为“file”,问题面板中输出信息文件那栏输出了文件名、行号、列号,不过行号、列号固定为1,如图:
    在这里插入图片描述
3.2.2.3、file、line、column

在正则表达式匹配输出信息时识别出来的文件名的匹配组号,有关正则知识请参考老猿在CSDN上《Python基础教程》下的博文《第11.16节 Python正则元字符“()”(小括号)与组(group)匹配模式》的相关介绍。

按照:
案例正则表达式:"^(.*):(\\d+):(\\d+):\\s+(error):\\s+(.*)$"
对错误信息:hello.cpp:3:10: error: myhead.h: 没有那个文件或目录

进行匹配,file的匹配组号为1,即第一个括号内匹配到的内容为文件名,类似的line、column为匹配到错误位置行号、列号的匹配组号,在上面例子中分别对应组号2和3。

3.2.2.4、endLine、endColumn

endLine、endColumn与line、column类似,不过有些代码的编译构建程序会输出错误代码的起止行号和列号,line、column匹配开始行号和列号,而endLine、endColumn匹配终止行号和列号。C++的编译器没有输出相关信息,因此无需配置。

3.2.2.5、severity

问题输出信息中匹配到的问题级别的匹配组号,在上面的例子中就是(error)这个匹配信息对应的匹配组号。problemMatcher和ProblemPattern都存在“severity”的属性,ProblemPattern又是problemMatcher的子属性,二者的“severity”属性关系请见《VSCode任务tasks.json中的问题匹配器problemMatcher和ProblemPattern的severity属性关系》的分析,相关情况请参考本文后面的测试情况说明。

3.2.2.6、code

用于设置正则表达式匹配问题报错信息中给出的错误源代码的匹配组号,在C++中的报错信息中存在有源代码信息,但是在报错信息后面单独一行输出,由于涉及多行匹配,老猿一直无法验证成功

没测试成功的原因可能有3个:

  1. vscode的版本过低,因为老猿使用的是国产操作系统,安装的vscode的版本是1.81.0,而windows下已经至少是1.20.0的版本了;
  2. 多行问题匹配器不适合C++的编译错误信息,可能在别的语言构建时可以;
  3. 老猿的配置方法不对。

老猿觉得前面两个原因的可能性占多数,因为老猿做了很多测试都无法支持多行输出信息的处理,详细请见博文下面的介绍。

3.2.2.7、message

用于设置正则表达式匹配问题报错信息中给出的具体错误信息的匹配组号,如果没有配置或配置为0,默认就是包含文件名等在内的整个问题信息。

3.2.2.8、loop

loop这个属性老猿仅从字面理解了,是指定多行问题匹配器中的最后一个模式是否应循环,只要它与一行匹配即可,仅对多行问题匹配器中的最后一个问题模式有效。老猿理解为多行问题信息匹配需要多个匹配器来匹配多行的信息,如果loop为true,则只要这个问题匹配器匹配到任意一行的输出信息即可。

因为涉及多行匹配,与code属性一样,用C++程序测试时没有测试通过,因此也不知道理解是否正确。

四、问题匹配器的一些测试案例及结果介绍

4.1、编译hello.cpp的tasks.json的基本配置

下面是老猿使用的编译hello.cpp的tasks.json的基本配置:

{"version": "2.0.0","tasks": [{"type": "cppbuild","label": "C/C++: g++ 生成活动文件","command": "/usr/bin/g++","args": ["-fdiagnostics-color=always","-g","-Wall","-Wextra","-O0","${workspaceFolder}/hello.cpp","-o","${fileDirname}/${fileBasenameNoExtension}"],"options": {"cwd": "${fileDirname}"},"problemMatcher": [              "$gcc"],"group": {"kind": "build","isDefault": true},"detail": "编译器: /usr/bin/g++"}]
}

这是初始配置,问题匹配器用的是预定义的$gcc。用该配置编译上述hello.cpp时,在终端窗口输出的错误信息如下:
在这里插入图片描述
目前看到仅一个报错:“/home/administrator/E_DRIVER/vcwork/test/hello.cpp:3:10: fatal error: myhead.h: 没有那个文件或目录”,这是因为遇到了致命错误,所以没有继续往下执行编译。下面是此时在问题控制面板的输出信息:
在这里插入图片描述
可以看到输出了三个error级别的错误信息,其中前2个是VSCODE的C++插件IntelliSense输出的,第三个是cpptools输出的,实际上就是上面配置的问题匹配器$gcc输出的。

4.2、测试新增一个问题匹配器以及problemMatcher和ProblemPattern的severity属性关系

修改问题匹配器配置如下:

 "problemMatcher": [   {"owner": "problem_1","severity": "warning","fileLocation": "absolute","pattern":            {"regexp": "^(.*):(\\d+):(\\d+):\\s+(fatal).*:\\s+(.*)$","file": 1,"line": 2,"column": 3,"severity": 4,"message": 5}},           "$gcc"]

注意该问题匹配器的配置有如下要点:

  1. problemMatcher."severity"的值为 “warning”;
  2. pattern."severity"的值为4,对应regexp的第4个匹配组号,对应匹配内容为(fatal)
  3. 配置了2个问题匹配器,分别是自定义的problem_1和预定义的$gcc

这样配置后,执行生成构建任务后,问题面板的输出信息如下:
在这里插入图片描述
可以看到:

  1. 原来基本配置显示的最左边的严重级别图标为error,修改问题匹配器后显示为warning对应的图标;
  2. 问题来源显示为新配置的problem_1;
  3. 错误信息由原来的“myhead.h: 没有那个文件或目录”变成了“没有那个文件或目录”。
    结合上述问题匹配器大家去理解一下为什么会有这些变化,有疑问在评论区提问。

通过这个配置可以说明如下情况:

  1. problemMatcher的severity属性优先ProblemPattern的severity属性;
  2. 多个问题匹配器是按顺序匹配的,匹配到一个后面的不再匹配。

4.3、去除problemMatcher的severity配置场景

将自定义的问题匹配器的problemMatcher的severity属性配置注释掉,同时将message的匹配组号调整为4,与pattern."severity"的值相同,配置如下:

     "problemMatcher": [   {"owner": "problem_1",// "severity": "warning","fileLocation": "absolute","pattern":            {"regexp": "^(.*):(\\d+):(\\d+):\\s+(fatal).*:\\s+(.*)$","file": 1,"line": 2,"column": 3,"severity": 4,"message": 4}},           "$gcc"],

可以看到执行构建任务时,问题面板输出内容如下:
在这里插入图片描述
可以看到输出的消息变为:fatal,问题严重级别图标变为error,相关结论大家可以参考《VSCode任务tasks.json中的问题匹配器problemMatcher和ProblemPattern的severity属性关系》的介绍。

4.3、新增两个定制化的problemMatcher配置场景

4.3.1、测试背景说明

由于测试代码中的#include "myhead.h"存在致命错误,导致编译程序无法往下执行,为了测试本场景,要求本次测试的代码是注释或去除了该行代码,此时编译报错信息为:

hello.cpp:10:12: warning: format ‘%s’ expects argument of type ‘char*’, but argument 2 has type ‘int’ [-Wformat=]printf("j=%s\n",j);^~~~~~~~ ~
hello.cpp:14:5: error: ‘hell’ was not declared in this scopehell("");^~~~
hello.cpp:14:5: note: suggested alternative: ‘ftell’hell("");^~~~ftell生成已完成,但出现错误。*  终端进程启动失败(退出代码: -1)
4.3.2、测试的问题匹配器配置

配置了三个问题匹配器,分别是problem_error、problem_warning和预定义的gcc,三个问题匹配器本身都没有配置severity属性。具体配置如下:

"problemMatcher": [   {"owner": "problem_error","fileLocation": "absolute","pattern":            {"regexp": "^(.*):(\\d+):(\\d+):\\s+(.*error).*:\\s+(.*)$","file": 1,"line": 2,"column": 3,"severity": 4,"message": 5}},   {"owner": "problem_warning","fileLocation": "absolute","pattern":            {"regexp": "^(.*):(\\d+):(\\d+):\\s+(.*warning|note).*:\\s+(.*)$","file": 1,"line": 2,"column": 3,"severity": 4,"message": 5}},               "$gcc"]

进行编译构建后,输出问题面板内容如下:
在这里插入图片描述

可以看到输出了4个问题,其中一个是C++ InelliSense输出的,其他三个是自定义问题匹配器输出的,大家应该可以理解输出信息为什么是这样吧?特别是最后一个显示的信息为什么是‘ftell’?不理解的在评论区提问吧。

4.4、测试捕获输出了源代码的问题

将问题匹配器换成如下:

"problemMatcher": [   {"owner": "problem_code","fileLocation": "absolute","pattern":            {"regexp": "^.*(printf).*$","file":1,"message": 1             }},            "$gcc"]

该问题匹配器试图匹配输出信息存在printf的语句,但经测试该问题匹配器无法捕获到问题,具体原因未知,如果有哪位大佬可以解惑,欢迎在评论区留言,老猿感激不尽。

4.5、测试捕获多行问题信息

将问题匹配器改成如下:

"problemMatcher": [   {"owner": "problem_multiline","fileLocation": "absolute","pattern": [           {"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|note|error):\\s+(.*)$","file": 1,"line": 2,"column": 3,"severity": 4,"message": 5},{"regexp": "(.*)","file":1,"message": 1,"loop":true}]},              "$gcc"]

上面的问题匹配器数组包含了两个问题匹配器,一个自定义的problem_multiline,一个gcc,其中problem_multiline配置了两个ProblemPattern问题模式。运行编译任务后,可以看到问题面板输出信息如下:
在这里插入图片描述
这个输出结果可以看到,针对note的告警信息,匹配了problem_multiline这个问题匹配器,其他的问题输出信息都没有匹配到problem_multiline,匹配到的问题匹配器的输出信息感觉是两个ProblemPattern对note所在的首行输出信息进行匹配之后叠加一起作为message输出,为什么这样老猿也没搞懂,欢迎各位大佬指教。

五、小结

本文介绍了VSCode任务tasks.json中的问题匹配器problemMatcher的配置项问题匹配模式ProblemPattern,包括官方定义以及老猿对每个ProblemPattern子对象的解读,有些内容是老猿测试验证后独家公布,同时对相关知识老猿也存在多处没有理解的地方,在正文中都以加粗字体显示,期待各位大佬指导。

写博不易,敬请支持

如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!

更多关于vscode使用方面的问题的内容请参考专栏《国产信创之光》的相关文章。

关于老猿的付费专栏

  1. 付费专栏《https://blog.csdn.net/laoyuanpython/category_9607725.html 使用PyQt开发图形界面Python应用》专门介绍基于Python的PyQt图形界面开发基础教程,对应文章目录为《 https://blog.csdn.net/LaoYuanPython/article/details/107580932 使用PyQt开发图形界面Python应用专栏目录》;
  2. 付费专栏《https://blog.csdn.net/laoyuanpython/category_10232926.html moviepy音视频开发专栏 )详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,对应文章目录为《https://blog.csdn.net/LaoYuanPython/article/details/107574583 moviepy音视频开发专栏文章目录》;
  3. 付费专栏《https://blog.csdn.net/laoyuanpython/category_10581071.html OpenCV-Python初学者疑难问题集》为《https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python图形图像处理 》的伴生专栏,是笔者对OpenCV-Python图形图像处理学习中遇到的一些问题个人感悟的整合,相关资料基本上都是老猿反复研究的成果,有助于OpenCV-Python初学者比较深入地理解OpenCV,对应文章目录为《https://blog.csdn.net/LaoYuanPython/article/details/109713407 OpenCV-Python初学者疑难问题集专栏目录 》
  4. 付费专栏《https://blog.csdn.net/laoyuanpython/category_10762553.html Python爬虫入门 》站在一个互联网前端开发小白的角度介绍爬虫开发应知应会内容,包括爬虫入门的基础知识,以及爬取CSDN文章信息、博主信息、给文章点赞、评论等实战内容。

前两个专栏都适合有一定Python基础但无相关知识的小白读者学习,第三个专栏请大家结合《https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python图形图像处理 》的学习使用。

对于缺乏Python基础的同仁,可以通过老猿的免费专栏《https://blog.csdn.net/laoyuanpython/category_9831699.html 专栏:Python基础教程目录)从零开始学习Python。

如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

老猿Python,跟老猿学Python!

☞ ░ 前往老猿Python博文目录 https://blog.csdn.net/LaoYuanPython ░

这篇关于VSCode任务tasks.json中的问题匹配器problemMatcher的问题匹配模式ProblemPattern详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/692081

相关文章

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

Android中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

JSON Web Token在登陆中的使用过程

《JSONWebToken在登陆中的使用过程》:本文主要介绍JSONWebToken在登陆中的使用过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录JWT 介绍微服务架构中的 JWT 使用结合微服务网关的 JWT 验证1. 用户登录,生成 JWT2. 自定义过滤

Java中StopWatch的使用示例详解

《Java中StopWatch的使用示例详解》stopWatch是org.springframework.util包下的一个工具类,使用它可直观的输出代码执行耗时,以及执行时间百分比,这篇文章主要介绍... 目录stopWatch 是org.springframework.util 包下的一个工具类,使用它

Java进行文件格式校验的方案详解

《Java进行文件格式校验的方案详解》这篇文章主要为大家详细介绍了Java中进行文件格式校验的相关方案,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、背景异常现象原因排查用户的无心之过二、解决方案Magandroidic Number判断主流检测库对比Tika的使用区分zip

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s