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

Regex 使正则表达式量词长度取决于以前的捕获组,regex,rust,Regex,Rust,我希望使用正则表达式来解析以整数n开头的字符串。空格后有n个字符,后面可能有更多的文本。我希望能捕捉到n和接下来的n个角色。这n个字符没有限制。换句话说,5 hello world应该与捕获组5和hello匹配 我尝试了这个正则表达式,但它无法编译,因为它的结构取决于输入:(\d+)。{\1} 有没有办法让正则表达式编译器执行我想要的操作,或者我必须自己解析它 我用的是Rust的regex板条箱,如果有必要的话。如果使用regex不可能,那么使用另一个更复杂的regex引擎是否可能 谢谢 正如@

我希望使用正则表达式来解析以整数n开头的字符串。空格后有n个字符,后面可能有更多的文本。我希望能捕捉到n和接下来的n个角色。这n个字符没有限制。换句话说,
5 hello world
应该与捕获组
5
hello
匹配

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

有没有办法让正则表达式编译器执行我想要的操作,或者我必须自己解析它

我用的是Rust的
regex
板条箱,如果有必要的话。如果使用
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]

正如@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 = $1\n";
print "2nd capture group = $2\n";
print "whole capture group = $&\n";
'
输出:

1st capture group = 5
2nd capture group = abcde
whole capture group = 5 abcde
[解释]

  • 如果在正则表达式中遇到
    (??{…})
    块,则其内容 动态扩展为
    Perl
    代码
  • 特殊变量
    $^N
    指的是上次捕获的
    并在本例中扩展为
    5
  • 然后将代码
    (?{{($^N)。“}}}})
    计算为
    {5}
    ,其中 表示后跟量词的点

如果您选择使用
Perl
,请尝试:

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

1st capture group = 5
2nd capture group = abcde
whole capture group = 5 abcde
[解释]

  • 如果在正则表达式中遇到
    (??{…})
    块,则其内容 动态扩展为
    Perl
    代码
  • 特殊变量
    $^N
    指的是上次捕获的
    并在本例中扩展为
    5
  • 然后将代码
    (?{{($^N)。“}}}})
    计算为
    {5}
    ,其中 表示后跟量词的点

您需要将字符串(如
“5”
转换为它所表示的整数,
5
)。你不能用正则表达式这样做。
n
的最大值是多少?
n
是一个32位整数,但为了方便解决问题,这可能会发生变化。您可以使用一个简单的正则表达式来获取
n
,然后在代码中将其转换为整数,然后提取感兴趣的字符串。您需要转换字符串,如
“5”
到它所表示的整数,
5
。你不能用正则表达式这样做。
n
的最大值是多少?
n
是一个32位整数,但为了方便解决问题,这可能会发生变化。您可以使用一个简单的正则表达式来获取
n
,然后在代码中将其转换为整数,然后提取感兴趣的字符串。您可以通过使用捕获索引稍微简化代码。e、 例如,
cap[1].parse().unwrap\u或(0)
。通过使用捕获索引,您可以在某种程度上简化代码。e、 例如,
cap[1].parse().unwrap\u或(0)