You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Raku的comb函数中使用Grammar中的正则表达式?

问题描述

我想在Raku的comb函数中使用Grammar内定义的正则表达式,而非独立正则表达式。比如在下面解析journalctl日志的代码里,我希望把MAIN子程序中的&h替换成类似&Journalctl::full_log的内容:

role Log {
  token preamble { ... };
  token message { <-preamble>* };
  regex full_log { <preamble> <message> };
}

grammar Journalctl does Log {
  token date { \S+\s\d\d\s\d\d\:\d\d\:\d\d};
  token hostname { \S* };
  token ctl_unit { <-[\[]>+ };
  token pid { \d+ };
  regex preamble { <date> <.ws> <hostname> <.ws> <ctl_unit> \[ <pid> \]\: };
}

sub MAIN( ) {
  my regex h { h. };
  for $*IN.comb(&h) -> $wof {  # FIXME
    say $wof;
  }
}

参考的journalctl日志示例:

Jun 25 14:45:54 cpu-hostname systemd-timesyncd[725]: Initial synchronization to time server 185.125.190.56:123 (ntp.ubuntu.com).
Jun 25 14:45:54 cpu-hostname systemd-resolved[722]: Clock change detected. Flushing caches.
解决方案

Grammar中定义的正则是类方法,无法直接通过&符号传递给comb(comb需要能直接匹配字符串的Callable),可以通过以下两种方式实现需求:

方法一:用闭包包装Grammar正则调用

将Grammar的正则调用封装成闭包,传递给comb:

sub MAIN( ) {
  for $*IN.comb(-> $str { so $str ~~ Journalctl::full_log }) -> $entry {
    say $entry;
  }
}

方法二:直接提取Grammar正则作为Callable

可以直接获取Grammar中定义的正则规则,作为Callable传入comb,同时修正原代码中message token的错误定义:

role Log {
  token preamble { ... };
  # 修正message定义:<-preamble>*是错误写法,改为匹配行内所有字符
  token message { \N* };
  regex full_log { <preamble> <message> };
}

grammar Journalctl does Log {
  token date { \S+\s\d\d\s\d\d\:\d\d\:\d\d};
  token hostname { \S* };
  token ctl_unit { <-[\[]>+ };
  token pid { \d+ };
  regex preamble { <date> <.ws> <hostname> <.ws> <ctl_unit> \[ <pid> \]\: };
}

sub MAIN( ) {
  my $full-log-rule = Journalctl.full_log;
  for $*IN.comb($full-log-rule) -> $entry {
    say $entry;
  }
}

额外说明

  • 原代码中Log角色的message token使用<-preamble>*是错误的,<-[...]>仅用于字符类否定,无法排除一个token,改用\N*可以匹配行内所有非换行字符,符合日志内容的格式。
  • comb会自动提取所有匹配正则的片段,结合修正后的full_log规则,可以正确拆分每条journalctl日志条目。

内容的提问来源于stack exchange,提问作者mikeLundquist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 23:36:00