मैं ऐसा कुछ पाने की कोशिश कर रहा हूं (काम नहीं करता):

match input {
    "next" => current_question_number += 1,
    "prev" => current_question_number -= 1,
    "goto {x}" => current_question_number = x,
    // ...
    _ => status = "Unknown Command".to_owned()
}

मैंने Regex के दो अलग-अलग संस्करणों की कोशिश की:

go_match = regex::Regex::new(r"goto (\d+)?").unwrap();
// ...
match input {
    ...
    x if go_match.is_match(x) => current_question_number = go_match.captures(x).unwrap().get(1).unwrap().as_str().parse().unwrap(),
    _ => status = "Unknown Command".to_owned()
}

तथा

let cmd_match = regex::Regex::new(r"([a-zA-Z]+) (\d+)?").unwrap();
// ...
if let Some(captures) = cmd_match.captures(input.as_ref()) {
        let cmd = captures.get(1).unwrap().as_str().to_lowercase();
        if let Some(param) = captures.get(2) {
            let param = param.as_str().parse().unwrap();
            match cmd.as_ref() {
                "goto" => current_question_number = param,
            }
        } else {
            match cmd.as_ref() {
                "next" => current_question_number += 1,
                "prev" => current_question_number -= 1,
            }
        }
    } else {
        status = "Unknown Command".to_owned();
    }

दोनों कुछ बहुत ही सामान्य करने के लिए एक हास्यास्पद लंबे और जटिल तरीके की तरह लगते हैं, क्या मुझे कुछ याद आ रहा है?

10
8176135 24 मई 2018, 12:02

2 जवाब

सबसे बढ़िया उत्तर

आप एक मास्टर Regex बना सकते हैं जो सभी दिलचस्प घटकों को कैप्चर करता है और फिर सभी कैप्चर किए गए टुकड़ों का Vec बना देता है। इसके बाद इस Vec का मिलान किया जा सकता है:

extern crate regex;

use regex::Regex;

fn main() {
    let input = "goto 4";
    let mut current_question_number = 0;

    // Create a regex that matches on the union of all commands
    // Each command and argument is captured
    // Using the "extended mode" flag to write a nicer Regex
    let input_re = Regex::new(
        r#"(?x)
        (next) |
        (prev) |
        (goto)\s+(\d+)
        "#
    ).unwrap();

    // Execute the Regex
    let captures = input_re.captures(input).map(|captures| {
        captures
            .iter() // All the captured groups
            .skip(1) // Skipping the complete match
            .flat_map(|c| c) // Ignoring all empty optional matches
            .map(|c| c.as_str()) // Grab the original strings
            .collect::<Vec<_>>() // Create a vector
    });

    // Match against the captured values as a slice
    match captures.as_ref().map(|c| c.as_slice()) {
        Some(["next"]) => current_question_number += 1,
        Some(["prev"]) => current_question_number -= 1,
        Some(["goto", x]) => {
            let x = x.parse().expect("can't parse number");
            current_question_number = x;
        }
        _ => panic!("Unknown Command: {}", input),
    }

    println!("Now at question {}", current_question_number);
}
5
Shepmaster 26 मई 2018, 00:36

आप इसके लिए str::split का उपयोग कर सकते हैं (खेल का मैदान)

fn run(input: &str) {
    let mut toks = input.split(' ').fuse();
    let first = toks.next();
    let second = toks.next();

    match first {
        Some("next") => println!("next found"),
        Some("prev") => println!("prev found"),
        Some("goto") => match second {
            Some(num) => println!("found goto with number {}", num),
            _ => println!("goto with no parameter"),
        },
        _ => println!("invalid input {:?}", input),
    }
}

fn main() {
    run("next");
    run("prev");
    run("goto 10");
    run("this is not valid");
    run("goto"); // also not valid but for a different reason
}

आउटपुट होगा

next found
prev found
found goto with number 10
invalid input "this is not valid"
goto with no parameter
4
user25064 25 मई 2018, 17:05