编写编译模式正则表达式

本文关键字:正则表达式 模式 编译 | 更新日期: 2023-09-27 18:36:43

考虑

行和列范围的最终工作解决方案:

(csharp
 "^ *''(?:[0-9]+>'')*''(''(?:[a-zA-Z]:'')?[^:('t'n]+'')(''([0-9]+''),''([0-9]+''),''([0-9]+''),''([0-9]+'')) *': ''(error''|warning'') *CS[0-9]+:)"
 1 (2 . 4) (3 . 5) )

下面的两个答案都非常有帮助;我现在对这个系统有了更好的了解。


摘要:我的正则表达式可以匹配输出字符串,但在编译错误正则表达式列表列表中无法匹配编译输出中的错误。

我发现编译模式正则表达式有点令人困惑。我已经编写了一个正则表达式,我知道它使用重建器和 compile.el 中的原始正则表达式来处理我的错误字符串。

40>f:''Projects''dev''source''Helper.cs(37,22,37,45):错误 CS1061:"foo.bar"不包含"函数"的定义,并且找不到接受类型为"foo.bar"的第一个参数的扩展方法"方法"(是否缺少 using 指令或程序集引用?

这是我的正则表达式:

(pushnew '(csharp
 "^ *''(?:[0-9]+>'')*''(''(?:[a-zA-Z]:'')?[^:('t'n]+'')(''([0-9]+''),''([0-9]+''),[0-9]+,[0-9]+) *': ''(?:error *CS[0-9]+:'')"
 2 3)
     compilation-error-regexp-alist-alist)

显然,我只是想找到输出的第一行/列对。(我很惊讶编译器输出 4 个数字而不是两个,但无论如何。

如果我们在 compile.el 中查看 edg-1 正则表达式:

    (edg-1
 "^''([^ 'n]+'')(''([0-9]+'')): ''(?:error''|warnin''(g'')''|remar''(k'')'')"
 1 2 nil (3 . 4))

所以我想我困惑的地方是如何通过论点的。在 edg-1 中,3 和 4 来自哪里?我猜他们与捕获组不对应?如果我通过重新构建器在格式正确的错误消息上运行 edg-1 正则表达式并进入子表达式模式,则 0 匹配整个匹配字符串,1 匹配文件名和路径,2 匹配行号。从查看文档(当我做 M-x 描述变量时),它似乎只关心子表达式在主表达式中的位置。无论哪种方式,我显然误解了一些东西。

我也尝试修改官方的csharp.el正则表达式来处理额外的两个数字,但没有运气。

(编辑,稍微修复了示例,更新了 csharp 正则表达式)

编写编译模式正则表达式

找到了一些这方面的信息。

此页面有一个简化的解释:
http://praveen.kumar.in/2011/03/09/making-gnu-emacs-detect-custom-error-messages-a-maven-example/

引用自页面 -

"Each elt has the form (REGEXP FILE [LINE COLUMN TYPE HYPERLINK
HIGHLIGHT...]).  If REGEXP matches, the FILE'th subexpression
gives the file name, and the LINE'th subexpression gives the line
number.  The COLUMN'th subexpression gives the column number on
that line"

所以看起来格式是这样的:

(REGEXP FILE [LINE COLUMN TYPE HYPERLINK HIGHLIGHT...])

再次查看正则表达式,它看起来像是修改后的 BRE。

 ^                   # BOS
 '( [^ 'n]+ ')       # Group 1
 (                   # Literal '('
 '( [0-9]+ ')        # Group 2
 )                   # Literal ')'
 : [ ] 
 '(?:
      error
   '|
      warnin'(g')    # Group 3
   '|
      remar'(k')     # Group 4
 ')

这是 edg-1

(edg-1
 "^''([^ 'n]+'')(''([0-9]+'')): ''(?:error''|warnin''(g'')''|remar''(k'')'')"
 1 2 nil (3 . 4))

哪里

"^''([^ 'n]+'')(''([0-9]+'')): ''(?:error''|warnin''(g'')''|remar''(k'')'')"
REGEXP ^^^^^^^^
 1     2    nil    (3 . 4)
 ^     ^     ^      ^^^^^
FILE LINE  COLUMN   TYPE

"TYPE is 2 or nil for a real error or 1 for warning or 0 for info.
TYPE can also be of the form (WARNING . INFO).  In that case this
will be equivalent to 1 if the WARNING'th subexpression matched
or else equivalent to 0 if the INFO'th subexpression matched."

因此,TYPE 是这种形式(警告 .信息)

In the regex,
if capture group 3 matched (ie. warnin'(g') ) it is equivalent to a warning.
If capture group 4 matched (ie. remar'(k') ) it is equivalent to info.  
One of these will match.  

夏普元素信息

查看您的csharp元素

"^ *''(?:[0-9]+>'')?''(''(?:[a-zA-Z]:'')?[^:('t'n]+'')(''([0-9]+''),''([0-9]+''),[0-9]+,[0-9]+) *': ''(?:error *CS[0-9]+:'')"
2 3 4

而且您的正则表达式(如下)实际上没有捕获组 4。
所以,你的文件行列 2 3 4
可能应该1 2 3

这是你的正则表达式,因为它的引擎看到它 -

 ^ 
 [ ]* 
 '(?:
      [0-9]+ > 
 ')?
 '(                            # Group 1
      '(?:
            [a-zA-Z] : 
      ')?
      [^:('t'n]+ 
 ')
 (                             # Literal '('
      '( [0-9]+ ')                # Group 2
      ,
      '( [0-9]+ ')                # Group 3
      ,
      [0-9]+
      ,
      [0-9]+ 
 )                             # Literal ')'
 [ ]* ': [ ] 
 '(?:
      error [ ]* CS [0-9]+ :
 ')

我的水晶球想出了一个奇怪的解释:compilation-error-regexp-alist-alist只是匹配规则的集合,但它没有说明使用哪些规则。 因此,如果要使用新规则,则需要向compilation-error-regexp-alist添加csharp

至于(3 . 4)的含义,见C-h v compilation-error-regexp-alist