如何将正则表达式替换中捕获的模式转换为大写?

时间:2018-06-23 01:54:40

标签: regex rust

我想用/test/test1代替TEST1:。这是我开始的:

extern crate regex; // 1.0.1

use regex::Regex;

fn main() {
    let regex_path_without_dot = Regex::new(r#"/test/(\w+)/"#).unwrap();

    let input = "/test/test1/test2/";

    // Results in "test1:test2/"
    let result = regex_path_without_dot.replace_all(input, "$1:");
}

我尝试使用

let result = regex_path_without_dot.replace_all(&input, "$1:".to_uppercase());

但我收到此错误:

error[E0277]: the trait bound `for<'r, 's> std::string::String: std::ops::FnMut<(&'r regex::Captures<'s>,)>` is not satisfied
  --> src/main.rs:10:41
   |
10 |     let result = regex_path_without_dot.replace_all(&input, "$1:".to_uppercase());
   |                                         ^^^^^^^^^^^ the trait `for<'r, 's> std::ops::FnMut<(&'r regex::Captures<'s>,)>` is not implemented for `std::string::String`
   |
   = note: required because of the requirements on the impl of `regex::Replacer` for `std::string::String`

如何实现此必需特征?有没有简单的方法可以做到这一点?

1 个答案:

答案 0 :(得分:5)

Regex::replace具有签名

<?php
    $re = '/(?<first>Transaction ID: (?<transId>\w{1,})\.)(.*)(?<second>Reference code: (?<refCode>\w{1,})\.)/m';
    $str = 'Your transaction was successful. Transaction ID: 453712046. Reference code: 1234326. Thank you!';

    preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

    // Print the entire match result
    var_dump($matches);
?>

Replacer通过以下方式实现:

  • pub fn replace<'t, R: Replacer>(&self, text: &'t str, rep: R) -> Cow<'t, str>
  • &'a str
  • ReplacerRef<'a, R> where R: Replacer
  • F where F: FnMut(&Captures) -> T, T: AsRef<str>

NoExpand<'t>没有实现,这是错误消息的直接原因。您可以通过将String转换为字符串切片来“修复”错误:

String

由于大写版本与小写版本相同,因此不会有任何有益的变化。

但是,通过闭包实现replace_all(&input, &*"$1:".to_uppercase() 很有用

Replacer

let result = regex_path_without_dot.replace_all(&input, |captures: &regex::Captures| {
    captures[1].to_uppercase() + ":"
});

这表明在理解此功能的工作方式或功能优先级方面存在根本错误。这跟说的一样:

replace_all(&input, "$1:".to_uppercase())

或者等效地,由于let x = "$1:".to_uppercase(); replace_all(&input, x) 是大写1,而1是大写$

$

调用“ let x = String::from("$1:"); replace_all(&input, x) ”之类的函数不会神奇地推迟到“以后”。