如何在 Rust 中获取重叠的正则表达式匹配结果?

4

我想要匹配特定字符后的两个字符。尾随值可能包含指定的字符,这是可以的,但我还需要捕获该指定字符作为下一个捕获组的开头。

以下代码应该说明我的意思:

extern crate regex;
use regex::Regex;


pub fn main() {
    let re = Regex::new("(a..)").unwrap();
    let st = String::from("aba34jf baacdaab");
    println!("String to match: {}", st);

    for cap in re.captures_iter(&st) {
        println!("{}", cap[1].to_string());
        // Prints "aba" and "aac",
        // Should print "aba", "a34", "aac", "acd", "aab"
    }
}

我该如何在不使用look around(regex crate在Rust中不支持)的情况下获得重叠捕获?是否有类似于Python中的东西(如此处所述),但在Rust中? 编辑: 按照BurntSushi5的建议,使用onig,我们得到以下结果:
extern crate onig;
use onig::*;

pub fn main() {
    let re = Regex::new("(?=(a.{2}))").unwrap();
    let st = String::from("aba34jf baacdaab");
    println!("String to match: {}", st);

    for ch in re.find_iter(&st) {
        print!("{} ", &st[ch.0..=ch.1+2]);
        // aba a34 aac acd aab, as it should.
        // but we have to know how long the capture is.
    }
    println!("");
}

现在这个问题是:由于向前查找组没有捕获,所以您必须知道正则表达式的长度。有没有办法在事先不知道长度的情况下捕获向前查找正则表达式?如果我们的正则表达式如(?=(a.+)),我们应该如何将它打印出来?


正则表达式库表示不支持环视,所以我甚至没有尝试。我收到了错误信息:错误:不支持环视,包括向前查看和向后查看 - Major
2个回答

5

你无法实现这个。你唯一的选择就是要么找到一个完全不同的方法,要么使用支持look-around的不同正则表达式引擎,例如onigpcre2


不可能获得第一个匹配项的偏移量,然后从一个代码点开始下一次搜索,重复此过程直到没有更多匹配项。 - Shepmaster
是的,我想对我来说这属于“不同的方法”。我认为它并不适用于所有情况。等我有机会时,我可以更新我的答案,包括一些相关代码。 - BurntSushi5
我使用了onig绑定,现在前瞻方法可以工作了。然而,这种特殊的方法需要知道捕获的长度,因为我们无法捕获前瞻部分内部的部分。你知道是否有打开这个选项的选项吗?我完全找不到相关文档。 - Major

1
我找到了一个解决方案,不幸的是它不是通过正则表达式实现的:
pub fn main() {
    print_char_matches ("aba34jf baacdaab", 'a', 2);
    //aba a34 aac acd aab, as it should.
}

pub fn print_char_matches( st:&str, char_match:char, match_length:usize ) {
    let chars:Vec<_> = st.char_indices().collect();

    println!("String to match: {}", st);

    for i in 0..chars.len()-match_length {
        if chars[i].1 == char_match {
            for j in 0..=match_length {
                print!("{}", chars[i+j].1);
            }
            print!(" ");
        }
    }
    println!("");
}

这是更加通用的,仅限ASCII。匹配提供的字符和指定数量的匹配后的数字。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接