Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split a string keeping the separators

Tags:

rust

Is there a trivial way to split a string keeping the separators? Instead of this:

let texte = "Ten. Million. Questions. Let's celebrate all we've done together.";
let v: Vec<&str> = texte.split(|c: char| !(c.is_alphanumeric() || c == '\'')).filter(|s| !s.is_empty()).collect();

which results with ["Ten", "Million", "Questions", "Let's", "celebrate", "all", "we've", "done", "together"].

I would like something that gives me :

["Ten", ".", " ", "Million", ".", " ", "Questions", ".", " ", "Let's", " ", "celebrate", " ", "all", " ", "we've", " ", "done", " ", "together", "."].

I am trying that kind of code (it assumes the string begins with a letter and ends with a 'non'-letter) :

let texte = "Ten. Million. Questions. Let's celebrate all we've done together.  ";
let v1: Vec<&str> = texte.split(|c: char| !(c.is_alphanumeric() || c == '\'')).filter(|s| !s.is_empty()).collect();
let v2: Vec<&str> = texte.split(|c: char| c.is_alphanumeric() || c == '\'').filter(|s| !s.is_empty()).collect();
let mut w: Vec<&str> = Vec::new();

let mut j = 0;
for i in v2 {
    w.push(v1[j]);
    w.push(i);
    j = j+1;
}

It gives me almost the result I wrote earlier but it's good :

["Ten", ". ", "Million", ". ", "Questions", ". ", "Let's", " ", "celebrate", " ", "all", " ", "we've", " ", "done", " ", "together", "."]

However is there a better way to code that ? Because I tried to enumerate on v2 but it didn't work, and it looks rough to use j in the for loop.

like image 396
Pierre Avatar asked Aug 27 '15 18:08

Pierre


People also ask

What happens when you split a string?

The split() method splits a string into a list. You can specify the separator, default separator is any whitespace. Note: When maxsplit is specified, the list will contain the specified number of elements plus one.

How do you split a string with spaces?

To split a string with space as delimiter in Java, call split() method on the string object, with space " " passed as argument to the split() method. The method returns a String Array with the splits as elements in the array.

Does split modify the original string?

The split() method splits a string into an array of substrings. The split() method returns the new array. The split() method does not change the original string. If (" ") is used as separator, the string is split between words.


1 Answers

Using str::match_indices:

let text = "Ten. Million. Questions. Let's celebrate all we've done together.";

let mut result = Vec::new();
let mut last = 0;
for (index, matched) in text.match_indices(|c: char| !(c.is_alphanumeric() || c == '\'')) {
    if last != index {
        result.push(&text[last..index]);
    }
    result.push(matched);
    last = index + matched.len();
}
if last < text.len() {
    result.push(&text[last..]);
}

println!("{:?}", result);

Prints:

["Ten", ".", " ", "Million", ".", " ", "Questions", ".", " ", "Let\'s", " ", "celebrate", " ", "all", " ", "we\'ve", " ", "done", " ", "together", "."]
like image 96
robinst Avatar answered Oct 06 '22 05:10

robinst