如何在 Rust 中使用正则表达式从右边查找?
How to find from right using a regex in Rust?
现在我已经颠倒了字符串和正则表达式以使用正则表达式模拟 rfind。下面是一个示例程序:
#[static_init::dynamic]
// static r: Regex = regex::Regex::new(r"a\d").unwrap();
static r: Regex = regex::Regex::new(r"\da").unwrap();
let mut s = "123a123a456";
let sr = s.chars().rev().collect::<String>();
let option = r.find(&sr).unwrap();
let start = s.chars().count() - option.end();
let end = s.chars().count() - option.start();
println!("start: {:#?}", start);
println!("end: {:#?}", end);
如您所见,我必须将正则表达式从 a\d
反转为 \da
以及字符串 s
以模拟 rfind
操作。有没有更简单的方法?谢谢。
regex-automata 有点支持这一点,而无需您自己进行反转。我说“有点”是因为你必须自己把东西缝合在一起:
use regex_automata::{dense, DFA};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let dfarev = dense::Builder::new()
.reverse(true)
.build_with_size::<u32>(r"a\d")?;
let dfafwd = dense::Builder::new()
.anchored(true)
.longest_match(true)
.build_with_size::<u32>(r"a\d")?;
let haystack = "123a123a456";
let mut at = haystack.len();
// This simple loop is wrong if the regex can match the empty string.
while let Some(start) = dfarev.rfind_at(haystack.as_bytes(), at) {
let end = dfafwd.find(haystack[start..].as_bytes())
.map(|i| start + i)
.expect("reverse match implies a forward match");
println!("match:{:?}:{:?}", (start, end), &haystack[start..end]);
at = start;
}
Ok(())
}
程序的输出是:
match:(7, 9):"a4"
match:(3, 5):"a1"
请注意,对于 regex-automata 0.1
,阅读 the section on differences between it and the regex crate 很重要。主要区别在于 regex-automata 0.1
仅提供完全编译的 DFA。 (下一个版本的 regex-automata 将不限于完全编译的 DFA。)
现在我已经颠倒了字符串和正则表达式以使用正则表达式模拟 rfind。下面是一个示例程序:
#[static_init::dynamic]
// static r: Regex = regex::Regex::new(r"a\d").unwrap();
static r: Regex = regex::Regex::new(r"\da").unwrap();
let mut s = "123a123a456";
let sr = s.chars().rev().collect::<String>();
let option = r.find(&sr).unwrap();
let start = s.chars().count() - option.end();
let end = s.chars().count() - option.start();
println!("start: {:#?}", start);
println!("end: {:#?}", end);
如您所见,我必须将正则表达式从 a\d
反转为 \da
以及字符串 s
以模拟 rfind
操作。有没有更简单的方法?谢谢。
regex-automata 有点支持这一点,而无需您自己进行反转。我说“有点”是因为你必须自己把东西缝合在一起:
use regex_automata::{dense, DFA};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let dfarev = dense::Builder::new()
.reverse(true)
.build_with_size::<u32>(r"a\d")?;
let dfafwd = dense::Builder::new()
.anchored(true)
.longest_match(true)
.build_with_size::<u32>(r"a\d")?;
let haystack = "123a123a456";
let mut at = haystack.len();
// This simple loop is wrong if the regex can match the empty string.
while let Some(start) = dfarev.rfind_at(haystack.as_bytes(), at) {
let end = dfafwd.find(haystack[start..].as_bytes())
.map(|i| start + i)
.expect("reverse match implies a forward match");
println!("match:{:?}:{:?}", (start, end), &haystack[start..end]);
at = start;
}
Ok(())
}
程序的输出是:
match:(7, 9):"a4"
match:(3, 5):"a1"
请注意,对于 regex-automata 0.1
,阅读 the section on differences between it and the regex crate 很重要。主要区别在于 regex-automata 0.1
仅提供完全编译的 DFA。 (下一个版本的 regex-automata 将不限于完全编译的 DFA。)