0

How do I split a string at the Nth occurrence of a character in Rust?

See also:

1 Answers1

2

You can get the position using match_indices() and then use split_at() to split the string. If you want to exclude the actual character it's a bit more complicated but you can use char_indices() to skip one. That feels a bit heavyweight but I couldn't find a simpler way.

/// Search `s` for the `n`th occurrence of `p`, then split the string
/// into two halves around that point.
fn split_at_nth_char(s: &str, p: char, n: usize) -> Option<(&str, &str)> {
    s.match_indices(p).nth(n).map(|(index, _)| s.split_at(index))
}

/// Same as `split_at_nth_char` but don't include the character.
fn split_at_nth_char_ex(s: &str, p: char, n: usize) -> Option<(&str, &str)> {
    split_at_nth_char(s, p, n).map(|(left, right)| {
        (
            left,
            // Trim 1 character.
            &right[right.char_indices().nth(1).unwrap().0..],
        )
    })
}

fn main() {
    dbg!(split_at_nth_char("this/is/a/string", '/', 1));
    dbg!(split_at_nth_char("this/is/a/string", '/', 2));
    dbg!(split_at_nth_char("this/is/a/string", '/', 3));
    dbg!(split_at_nth_char_ex("this/is/a/string", '/', 1));
}

Output:

[src/main.rs:19] split_at_nth_char("this/is/a/string", '/', 1) = Some(
    (
        "this/is",
        "/a/string",
    ),
)
[src/main.rs:20] split_at_nth_char("this/is/a/string", '/', 2) = Some(
    (
        "this/is/a",
        "/string",
    ),
)
[src/main.rs:21] split_at_nth_char("this/is/a/string", '/', 3) = None
[src/main.rs:22] split_at_nth_char_ex("this/is/a/string", '/', 1) = Some(
    (
        "this/is",
        "a/string",
    ),
)