मैं YMD तिथि को nom लाइब्रेरी द्वारा चार रूपों ("20190919", "2019.09.19", "2019-09-19", और "2019/09/19") में पार्स करना चाहता हूं।

मैंने iso8601 पार्सर से शुरुआत की जो केवल "YYYY" को पार्स करता है -एमएम-डीडी" फॉर्म। और मैंने विभाजक से मिलान करने और अगले मिलान के लिए इसे पुन: उपयोग करने का प्रयास किया जैसे रेगेक्स (\d{4})([ .-/]?)(\d{2})\2(\d{2})

पता चला कि यह कोड काम करता है:

fn parse_ymd(i: &[u8]) -> IResult<&[u8], DateType> {
    let (i, y) = year(i)?;

    // Match separator if it exist.
    let (i, sep) = opt(one_of(".-/"))(i)?;

    let (i, m) = month(i)?;

    // If first separator was matched then try to find next one.
    let (i, _) = if let Some(sep) = sep {
        tag(&[sep as u8])(i)?
    } else {
        // Support the same signature as previous branch.
        (i, &[' ' as u8][..])
    };

    let (i, d) = day(i)?;

    Ok((
        i,
        DateType::YMD {
            year: y,
            month: m,
            day: d,
        },
    ))
}

लेकिन जाहिर तौर पर यह अजीब लग रहा है।

क्या इसे और अधिक उपयुक्त तरीके से करने के लिए कुछ नाममात्र उपकरण हैं?

(यह प्रश्न nom कार्यक्षमता के बारे में है, और वहां काम कैसे करें। केवल इस विशेष उदाहरण के बारे में नहीं।)

0
Argentumbolo 19 सितंबर 2019, 16:09

1 उत्तर

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

आपका समाधान काफी सभ्य है। केवल एक ही सुझाव है जो मैं वास्तव में पेश कर सकता हूं:

fn parse_ymd(i: &[u8]) -> IResult<&[u8], DateType> {
    ...

    // If first separator was matched then try to find next one.
    let i = match sep {
        Some(sep) => tag(&[sep as u8])(i)?.0,
        _ => i,
    };

    ...
}

आप सीधे टपल तत्व तक पहुँचने के सिंटैक्स से परिचित नहीं हो सकते हैं। रस्ट बुक:

पैटर्न मिलान के माध्यम से विनाश के अलावा, हम एक अवधि (।) का उपयोग करके सीधे एक टपल तत्व तक पहुंच सकते हैं, उसके बाद उस मूल्य के सूचकांक का उपयोग कर सकते हैं जिसे हम एक्सेस करना चाहते हैं।

इस मामले में, यह आपको दो भुजाओं के हस्ताक्षर से मेल खाने की कोशिश करने की अजीबता से बचाता है।

1
edwardw 19 सितंबर 2019, 16:16