Se on moro,
Ensimmäisen kerran sitten ~16 kk. Unohtakaamme aiemmat konversaatiomme, joidenka takia Putkasta poistuin koko täksi ajaksi. Ei jatketa tästä aiheesta sen enempiä, vaan mennään asiaan...
Haluan luoda säännöllisen lausekkeen, joka matchaa seuraavissa kohdissa ja palauttaa alleviivatut kohdat capture grouppeina:
Näistä kolme ensimmäistä matchaa juuri kuten pitääkin, mutta viimeinen, neljäs, ei jostain ihmeen syystä matchaa lainkaan. Tässä on nyt jostain aivan pienestä kyse. Muutamasta merkistä. Mutta mikä ja missä? Lisäksi nuo capture groupit pitäisi korjata.
Tässä on sitten se tähän mennessäni yrittämäni lauseke:
/(?:([1-9]|2[1-9]|30|31)(?:\.|) (tammi|helmi|maalis|huhti|touko|kesä|heinä|elo|syys|loka|marras|joulu)kuuta|([1-9]|2[1-9]|30|31)\.([1-9]|1[0-2]).([0-9]{4}|[0-9]{2})|(tammi|helmi|maalis|huhti|touko|kesä|heinä|elo|syys|loka|marras|joulu)kuun ([1-9]|2[1-9]|30|31)\.)/gi
Kiitokset jo etukäteen!
P.S. Vapaaehtoinen saa halutessaan myös lyhentää lauseketta. Noin kauhian pitkä ei näytä oikein kivalle.
P.P.S. Käytetään JavaScriptissä. Tätä käytetään ainoastaan työkaluna client-sidellä, joten server-side tarkistusta ei tehdä. "Yleinen keskustelu" valittu, koska sivutaan enemmän kuitenkin säännöllisiä lausekkeita kuin sitä itse JavaScriptiä.
En oikein ymmärrä, millä kohdalla edes ajattelit matchaavasi sen. Lausekkeessasi on vain kolme kohtaa, joista ensimmäinen ja viimeinen käsittelevät sanallisia kuukausia ja keskimmäinen vaatii vuoden joko kaksi- tai nelinumeroisena. Ehkäpä helpointa on lisätä tuohon vuosikohtaan ?-merkki sulkujen perään tai yksi |-viiva lisää sulkujen sisään, jotta myös tyhjä vuosi kelpaa.
Tuo linkittämäsi nettipalvelu näyttää toimivan kummallisesti: siinä säännöllinen lauseke ottaa lyhimmän mahdollisen tekstin, vaikka pidempikin kävisi. Jos oikeasti ohjelmoit tuollaisessa ympäristössä, ei varmaan auta kuin lisätä erikseen neljäs kohta, jossa ei ole vuotta lainkaan.
Nykyinen lausekkeesi hylkää 20. päivän kaikissa kolmessa tapauksessa.
Toivottavasti olet huomioinut myös, että nykyinen lausekkeesi hyväksyy myös tekstin abc11.12.134abc, jolloin saat talteen kohdat 11, 12 ja 13. Ehkä lausekkeen alussa ja lopussa pitäisi olla vielä ^ ja $ tai vaikka edes \b (siis lainausmerkeissä useissa kielissä "\\b").
Metabolix kirjoitti:
Nykyinen lausekkeesi hylkää 20. päivän kaikissa kolmessa tapauksessa.
Niinpä näyttäisi tekevän, kuten myös 10. päivän.
****
Korjailin ehdotuksiesi pohjalta ja päädyin tähän:
/(?:([1-9]|1[0-9]|2[0-9]|30|31)(?:\.|) (tammi|helmi|maalis|huhti|touko|kesä|heinä|elo|syys|loka|marras|joulu)kuuta|([1-9]|1[0-9]|2[1-9]|30|31)\.([1-9]|1[0-2]).([0-9]{4}|[0-9]{2})|([1-9]|1[0-9]|2[1-9]|30|31)\.([1-9]|1[0-2])\.|(tammi|helmi|maalis|huhti|touko|kesä|heinä|elo|syys|loka|marras|joulu)kuun ([1-9]|1[0-9]|2[0-9]|30|31)\.)/gi
Minun mielestäni tuo näyttäisi toimivan, mutta vielä ulkopuolisen apu toiminnan tarkastamisessa olisi paikallaan.
En tiedä lainkaan, mutta saako capture groupit jotenkin järkevästi siten, että esimerkiksi jos muotona on esim. marraskuun 25. että saisin ne kahdessa ekassa capture groupissa enkä kahdessa viimeisessä (muut ovat NULL)?
Keskellä on yhä kahdesti virhe 20. päivän suhteen. Lisäksi välissä on yksi piste ilman \-merkkiä.
Tietääkseni tyhjiä ryhmiä ei voi ohittaa. JavaScriptissa voit kuitenkin helposti tehdä silmukan, joka käy läpi kaikki funktion argumentit ja ottaa siitä talteen vain ei-tyhjät alkiot.
Hyvä. Koitetaan vielä kerran:
/(?:([1-9]|1[0-9]|2[0-9]|30|31)(?:\.|) (tammi|helmi|maalis|huhti|touko|kesä|heinä|elo|syys|loka|marras|joulu)kuuta|([1-9]|1[0-9]|2[0-9]|30|31)\.([1-9]|1[0-2])\.([0-9]{4}|[0-9]{2})|([1-9]|1[0-9]|2[0-9]|30|31)\.([1-9]|1[0-2])\.|(tammi|helmi|maalis|huhti|touko|kesä|heinä|elo|syys|loka|marras|joulu)kuun ([1-9]|1[0-9]|2[0-9]|30|31)\.)/gi
Entä pystynkö vielä saamaan tiedon JavaScriptille siitä, että mikä päivämäärätyyppi (25.11., 25.11.2013, 25. marraskuuta jne.) tunnistettiin tekstistä, ilman että minun pitää luoda toinen säännöllinen lauseke sitä [tunnistusta] varten?
Näet tunnistetun tyypin siitä, missä ryhmissä on tietoa: jos ryhmässä 1 on tietoa, tiedät, että päivämäärän muoto on ”25. marraskuuta”.
Niinpä tietysti! En taas ajatellut loppuun asti. :)
Aihe on jo aika vanha, joten et voi enää vastata siihen.