使正则表达式量词长度取决于以前的捕获组



我希望使用正则表达式来解析以整数n开头的字符串。空格后有n个字符,之后可能会有更多的文本。我希望捕获 n 和后面的n个字符。对这n个字符没有任何约束。换句话说,5 hello world应与捕获组匹配5hello

我尝试了这个正则表达式,但它无法编译,因为它的结构取决于输入:(d+) .{1}.

有没有办法让正则表达式编译器做我想做的事,还是我必须自己解析它?

我正在使用 Rust 的regex箱,如果这很重要的话。如果regex不可能,那么另一个更复杂的正则表达式引擎是否可能?

谢谢!

正如@Cary Swoveland 在评论中所说,如果不对各种可能的长度进行硬编码,这在正则表达式中是不可能的。

但是,从匹配的数字中获取具有长度的匹配字符串的子字符串并不难:

use regex::Regex;

fn main() {
let re = Regex::new(r"(d+) (.+)").unwrap();
let test_str = "5 hello world";
for cap in re.captures_iter(test_str) {
let length: usize = cap[1].parse().unwrap_or(0);
let short_match: String = cap[2].chars().take(length).collect();
println!("{}", short_match); // hello
}
}

如果您知道您只会处理 ASCII 字符(没有 Unicode、重音符号等(,那么您可以使用更简单的切片语法let short_match = &cap[2][..length];

如果您可以选择Perl,请尝试:

perl -e '
$str = "5 abcdefgh";
$str =~ /(d+) ((??{".{".($^N)."}"}))/;
print "1st capture group = $1n";
print "2nd capture group = $2n";
print "whole capture group = $&n";
'

输出:

1st capture group = 5
2nd capture group = abcde
whole capture group = 5 abcde

[说明]

  • 如果在正则表达式中遇到(??{...})块,其内容 作为Perl代码动态扩展。
  • 特殊变量$^N是指last captured group并随着案例中的5而扩展。
  • 然后将代码(??{".{".($^N)."}"})评估为.{5}表示一个点,后跟一个量词。

最新更新