如何在Rust中获得重叠的正则表达式捕获?

时间:2019-08-14 14:46:59

标签: regex rust

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

此代码应说明我的意思:

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"
    }
}

如何在不使用环顾四周的情况下获得重叠捕获(Rust不支持regex板条箱)?是否有与Python(as mentioned here)相似但在Rust中相似的东西?

编辑:

使用BurnigSushi5建议的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.+))之类的正则表达式,将如何打印出来?

2 个答案:

答案 0 :(得分:2)

不能。您唯一的办法是完全找到其他方法,或者使用支持onigpcre2之类的环顾四周的正则表达式引擎。

答案 1 :(得分: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。匹配提供的字符和匹配后指定的位数。