Eroja regexp-kirjastoissa

Regexp-kirjastot ovat funktionaalisesti kaikki samanlaisia. Vai ovatko?

Eivät sittenkään. Osassa on mietitty vähän hämärämpiä käyttötapauksia, ja mahdollistettu muun muassa osittaisen matchin erottaminen epäonnistuneesta matchista. Kaikkein yleisikäyttöisin rajapinta olisi sellainen, joka mahdollistaisi täyden streamauksen, mutta se on harvinainen.

Otetaan esimerkki käyttötapauksesta: webissä on sivu, ja sivulla lomake, jossa on kenttiä, joilla on jotain muotovaatimuksia. Kehittäjä määrittelee muotovaatimuksen regexpillä. Halutaan dynaamisesti päivittyvä feedback, joka osaa kertoa, ei pelkästään onko kenttään kirjoitettu data kelvollista tai kelvotonta, vaan myös että voisiko se olla kelvollista, jos siihen lisättäisiin vielä jotain. Näin esim. luottokorttinumero olisi kesken kirjoittamisensa tilassa “ei vielä ok, mutta jos kirjoitat lisää, voisi olla ok”.

Tämän toteuttaminen pelkällä regexpin match-metodilla on hieman hankalaa. Aidoille regexpeille voidaan toteuttaa automaattinen transformaatio, joka muuttaa yhden regexpin toiseksi, joka matchaa kaikkiin ensimmäisen valideihin prefikseihin. Jos regexpejä laajennetaan epäaidoiksi sallimalla back referencet, tämä strategia ei enää edes toimi.

PCRE:ssä (C-kirjasto) erottelu saadaan aikaan antamassa pcre_exec:ille flageissa PRCE_PARTIAL_HARD, ja tunnistamalla paluuarvona PCRE_ERROR_PARTIAL (vastakohtana PCRE_ERROR_NOMATCH:ille). (Englanninkielinen termi on partial match.)

Muita tutkiessa vastaan tulleita kirjastoja, joissa tämä onnistuu, on Boost (C++) ja JRegex (Java). Boostia voi pitää jossain määrin standardina C++-ympyröissä. Javassa useimmat ammatinharjoittajat käyttävät standardikirjaston regexpejä, eikä tule mieleenkään, että parempikin ratkaisu (ja kyllä, JRegex on monilla tavoin parempi) on olemassa.

Pythonin standardikirjasto ei tätä tue, eikä laajennustakaan löydetty. Samoin kävi Javascriptin tapauksessa.

Oikeastaan ainoa asia, joka jäi enemmän häiritsemään, oli Javascript. Alkuperäinen käyttötapaushan haluttaisiin tietysti toteuttaa Javascriptillä, koska kyseessä on selaimessa tehtävä tarkistus.

Jos tarinassa on mitään varsinaista opetusta, se on se, että sen jälkeen, kun joku ominaisuus on saavuttanut kielen standardikirjaston, viat, jotka siihen ovat jääneet, ovat ikuisia. Vaikka ne korjattaisiinkin laajennukseen, suurin osa kehittäjistä käyttää standardikirjastoa. Tämä ei tietenkään koske suoranaisia bugeja toteutuksessa, koska ne on helppo korjata, vaan tällaisia korkeamman tason ajatusvirheitä siitä, mikä on mahdollisten käyttötapausten kenttä.

Niin, se täysi streamaus: kuvitellaan tilanne, jossa matchattava sisältö on pitkää, syöte tulee streamista ja tulos menee streamiin. Tällöin olisi hyötyä regexp-matcherista, jolle syöte voidaan antaa mielivaltainen pala kerrallaan, ja joka aina palan jälkeen osaa sanoa, missä tilassa on. Nämä tilat ovat no match, match ja ei voida tietää vielä, eli osittainen match.

Yleiskäyttöisiä palikoita suunnitellessa on aina ristivetoa streamattavien rajapintojen laajemman käytettävyyden ja kerralla asiat tekevien rajapintojen implementoinnin helppouden välillä. Aina oikeaa valintaa ei ole.

Tämän artikkelin on kirjoittanut Teemu Kalvas ja sitä ovat sittemmin muokanneet muut Codenton työntekijät.

Haastava kielenkäyttö

Uuden vuoden aattona Arto Nyberg haukkui radiossa sanaa “haaste” sisäsiistiksi konsulttislangiksi, “joka ei kerro elämästä sen oikeita asioita.”

En aio rynnätä eturintamaan puolustamaan sanan “haaste” kunniaa. En, vaan ammun sitä selkään näppäimistöni takaa. Inhoan koko sanaa – tai oikeastaan sen väärinkäyttöä.

Elävät kielet ovat täynnä värikkäitä ilmaisuja, jotka ovat syntyneet ihmisten taisteluista maailmankaikkeutta vastaan. Palaverin sopiminen tusinan kiireisen päättäjän kanssa vaatii työtä ja aikaa; se on siis työlästä. Lähikaupan kylmäketju katkeaa usein; kyseessä on ongelma. Ulkomainen ulkoistuskumppani vastaa vain joka kolmanteen sähköpostiin ja siihenkin asian vierestä; kommunikaatio on hankalaa.

Haasteella on sanana paikkansa. Sen käyttäminen vihjaa, että yksilö tai yhteisö on päättänyt ryhtyä tarmokkaasti toimeen muuttamaan vallitsevia olosuhteita. Haaste on otettu vastaan. Usein lopputuloksena on jotain positiivista – henkilökohtaista kasvua, suurempi markkinaosuus ja niin edelleen.

Miten ylläolevat virkkeet sopivat tähän?

Palaverin ajan löytäminen on haastavaa. Kenelle? Kenen osaaminen kasvaa siitä, jos tämä haaste otetaan vastaan ja voitetaan?

Kylmäketjun ylläpidossa on ollut runsaasti haasteita. Miten vakavia? Onko kylmäketju katkennut vai onko sen ylläpito kallista? Sana haaste peittää tässä tärkeää informaatiota.

Lopuksi rajatapaus: Kommunikaatio on haastavaa. Tässä tapauksessa alkuperäisen lauseen sanan “hankala” käyttö piilottaa yksityiskohtia. Se kuitenkin paljastaa enemmän puhujan asenteesta kuin kevyesti heitetty “haastava.” Rivien väleistä voi lukea, että kommunikaation vaikeus on hyväksytty vallitsevaksi asiantilaksi. Jos puhuja on kuitenkin motivoitunut parantamaan yhteistyötä kumppanin kanssa, “haaste” saattaakin sopia tilanteeseen paremmin.

Taitava konsultti oppii asiakkaan käyttämän kielen ja kertoo oman viestinsä asiakkaan käyttämillä termeillä. Jos asiakkaalla on ongelma, konsulttikin kutsuu sitä ongelmaksi.

Ymmärrän hyvin “haasteen” houkutuksen. Miten kutkuttavaa onkaan ohjelmoida asiakas näkemään tilanteensa positiivisemmassa valossa! Tällaisessa interventiossa on samat vaarat kuin antibiooteissa; liiallinen käyttö johtaa resistenssiin. Hyvä sana muuttuu “konsulttipotaskaksi.” (Ja ah, toimiiko asioiden suora kertominen koskaan? Parempi, että asiakas itse oivaltaa ongelmansa olevan haaste, sen sijaan että se suoraan hänelle kerrottaisiin…)

Uuden vuoden toiveena pyydän kahta asiaa. Pyydän, että “haasteet” jätetään vuoteen 2011 ja tästä vuodesta tehdään ongelmien, hankaluuksien, kommervenkkien ja takaiskujen vuosi!

Tämän artikkelin on kirjoittanut Antti Rasinen ja sitä ovat sittemmin muokanneet muut Codenton työntekijät.