Разделите строку на строки и найдите определенную строку c в диапазоне символов в Rust - PullRequest
0 голосов
/ 13 июля 2020

Цель состоит в том, чтобы обрезать строку по строкам и выбрать именно ту строку, где находится указанный c диапазон. Как это можно сделать с помощью итераторов в ржавчине?

let my_string = "Some small words, they're this.\nTogether";
let stripped_lines = ["Some small words, they\'re this.", "Together"];
// Important word where the char is located with inclusive range

range = Range {start: 33, end:41}
let chosen_line = "Together"

\n считается разделителем для новой строки, а \ не учитывается, так как это форматирование.

То, что я пробовал до сих пор:

let chosen_line = my_string.lines()
    .enumerate()
    .map(|(lineno, content)| (lineno + 1, content))
    .skip_while(|(lineno, _)| range.start < lineno)
    .take_while(|(lineno, _)| range.end >= lineno)
    .map(|(_, content)| content)
    .collect::<Vec<&'_ str>>();

Это не сработало. Я не знаю, как объединить logi c перечисления строк и выбора ограничения char.

Учтите, что диапазон ограничен определенной строкой c и никогда не будет находиться между строками (начальная и конечная в разных строках)

Ответы [ 2 ]

2 голосов
/ 13 июля 2020

Вы можете получить строку, в которой находится какой-либо символ (по байтовому индексу), подсчитав, сколько новых строк идет перед ним:

string[..index].chars().filter(|x| x == '\n').count()

Что вы хотите, чтобы произошло, если начало и конец диапазона не в одной строке? Вам нужна ошибка, диапазон индексов строк или только индекс начала диапазона? Вы можете просто вычислить и то, и другое, и при необходимости соответствующим образом обработать случай различных строк.

NB: если вам нужно несколько запросов в одной строке, вышеуказанное может быть медленным для больших строк. Вы можете предварительно вычислить список новых строк один раз (который вы сохраняете вместе со строкой), а затем использовать двоичный поиск:

// once:
let newlines = string.char_indices().filter_map(|(ix,c)| if c == '\n' {Some(ix)} else {None}).collect::<Vec<_>>();
// for each lookup:
newlines.binary_search(&index).unwrap_or_else(|x| x)
1 голос
/ 13 июля 2020

Предполагая, что я правильно понял ваш вопрос и что вы хотите сделать, это получить все строки, содержащие подстроку символов из многострочного текста:

  1. Получить подстроку [33..41] для сопоставления с This уродливо, но я не знаю другого способа получить фрагмент строки char без извлечения зависимостей
    let my_string = "Some small words, they're this.\nTogether";
    let stripped_lines = ["Some small words, they\'re this.", "Together"];

    let substring = my_string
        .chars()
        .enumerate()
        .filter_map(|(i, c)| match (33..41).contains(&i) {
            true => Some(c),
            false => None,
        })
        .collect::<String>();
Filter_map массив строк к строкам, содержащим подстроку
    let chosen_line: String = stripped_lines
        .iter()
        .filter_map(|l| match l.contains(&substring) {
            true => Some(String::from(*l)),
            false => None,
        })
        .collect();

Rust детская площадка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...