首页 > 解决方案 > 正则表达式:有一个单行符吗?

问题描述

我想尽快在多个大文本文件(每个 200MB)中搜索。我正在使用命令行工具ripgrep,我只想调用它一次。

在以下字符串中:

***foo***bar***baz***foo***bar***baz

***代表不同类型和数量的字符。)

我想匹配baz,但前提是它遵循第一次出现foo***bar***

所以 in ***foo***bar***baz***foo***bar***bazit 匹配第一个baz 并且 in ***foo***bar***qux***foo***bar***bazit 不匹配任何内容。

我尝试了几种解决方案,但没有奏效。这可以用一个正则表达式来完成吗?

标签: regexripgrep

解决方案


我很确定在这种情况下正则表达式是多余的。一个简单的系列就find可以完成这项工作:

fn find_baz(input: &str) -> Option<usize> {
    const FOO: &str = "foo";
    const BAR: &str = "bar";

    // 1: we find the occurrences of "foo", "bar" and "baz":
    let foo = input.find(FOO)?;
    let bar = input[foo..].find(BAR).map(|i| i + foo)?;
    let baz = input[bar..].find("baz").map(|i| i + bar)?;

    // 2: we verify that there is no other "foo" and "bar" between:
    input[bar..baz]
        .find(FOO)
        .map(|i| i + bar)
        .and_then(|foo| input[foo..baz].find(BAR))
        .xor(Some(baz))
}

#[test]
fn found_it() {
    assert_eq!(Some(15), find_baz("***foo***bar***baz***foo***bar***baz"));
}

#[test]
fn found_it_2() {
    assert_eq!(Some(27), find_baz("***foo***bar***qux***foo***baz"));
}

#[test]
fn not_found() {
    assert_eq!(None, find_baz("***foo***bar***qux***foo***bar***baz"));
}

#[test]
fn not_found_2() {
    assert_eq!(None, find_baz("***foo***bar***qux***foo***"));
}

推荐阅读