我可以使用'std::path::path`';s`strip_prefix`替换动态前缀?

我可以使用'std::path::path`';s`strip_prefix`替换动态前缀?,path,rust,Path,Rust,我之所以对此感兴趣,是因为我的路径中有一部分将保持不变,但我希望将其与所有父项一起删除 所以如果我们说 some/unknown/path/foo/bar/baz 我想回去 bar/baz 但我希望我只知道foo/…直接走我关心的那部分路 也许strip\u prefix是一种错误的方法,因此如果有更好的方法,我当然希望有人指出这个方向。strip\u prefix不会做你想做的事,因为它要求你知道要剥离的前缀。但是,您可以使用获取路径组件上的迭代器,然后使用标准的迭代器方法仅从所需的部分构

我之所以对此感兴趣,是因为我的路径中有一部分将保持不变,但我希望将其与所有父项一起删除

所以如果我们说

some/unknown/path/foo/bar/baz
我想回去

bar/baz
但我希望我只知道
foo/…
直接走我关心的那部分路


也许
strip\u prefix
是一种错误的方法,因此如果有更好的方法,我当然希望有人指出这个方向。

strip\u prefix
不会做你想做的事,因为它要求你知道要剥离的前缀。但是,您可以使用获取路径组件上的迭代器,然后使用标准的
迭代器
方法仅从所需的部分构建新的
PathBuf

下面是一个例子():

(这将分配一个新的
路径buf
。显示如何在不分配的情况下获取引用原始路径的
&Path
。)

然后,您可以使用或plus来获取可以转换为
字符串的内容

另请参见:

我认为,值得展示一些非分配版本

使用路径:带前缀 要使用,您需要知道前缀。我们可以沿着原始路径的s向上走,直到找到一个“foo”

使用std::path::path;
fn thing1

(路径:&P)->结果 哪里 P:AsRef+?尺寸, { 让original=path.as_ref(); 让mut prefix=original; while!前缀。以“foo”结尾{ prefix=匹配prefix.parent(){ 一些(p)=>p, 无=>返回错误(()), }; } 原始.strip_前缀(prefix).map_err(| | |()) } fn main(){ 设x=thing1(“some/unknown/path/foo/bar/baz”); println!(“{:?}”,x); }

使用迭代器 我们可以越过这条小路,它不是“福”。一旦我们对迭代器进行了足够的改进,就可以得到剩余的

使用std::path::path;
fn内容2

(路径:&P)->&path 哪里 P:AsRef+?尺寸, { 设path=path.as_ref(); 设muti=path.iter(); 对于i.by_ref()中的uu,take_uwhile(| c |*c!=“foo”){ i、 as_path() } fn main(){ 设x=thing2(“some/unknown/path/foo/bar/baz”); println!(“{:?}”,x); }


当“foo”不存在时,这将返回一个空路径。

是否要像
strip\u prefix
那样返回
路径
,或者是否可以构建一个新的
PathBuf
并返回该路径?最终我需要一个
字符串
——因此,如果这样我们就可以返回
PathBuf
let p = path::Path::new("some/unknown/path/foo/bar/baz");
let q: path::PathBuf = p.iter()   // iterate over path components
    .skip_while(|s| *s != "foo")  // skip everything before "foo"
    .skip(1)                      // skip "foo" itself
    .collect();                   // collect the rest into a PathBuf
println!("{:?}", q); // prints "bar/baz"
use std::path::Path;

fn thing1<P>(path: &P) -> Result<&Path, ()>
where
    P: AsRef<Path> + ?Sized,
{
    let original = path.as_ref();
    let mut prefix = original;

    while !prefix.ends_with("foo") {
        prefix = match prefix.parent() {
            Some(p) => p,
            None => return Err(()),
        };
    }

    original.strip_prefix(prefix).map_err(|_| ())
}

fn main() {
    let x = thing1("some/unknown/path/foo/bar/baz");
    println!("{:?}", x);
}
use std::path::Path;

fn thing2<P>(path: &P) -> &Path
where
    P: AsRef<Path> + ?Sized,
{
    let path = path.as_ref();
    let mut i = path.iter();

    for _ in i.by_ref().take_while(|c| *c != "foo") {}

    i.as_path()
}

fn main() {
    let x = thing2("some/unknown/path/foo/bar/baz");
    println!("{:?}", x);
}