Regneark og regexp

Som nevnt i forrige innlegg puslet jeg litt med egne tilpassinger av Portal in the Pages sitt statistikkregneark. Det var allerede lagt inn en fane for Read Harder, og den modifiserte jeg like gjerne til å være generell for utfordringer, slik at jeg kan ha kaosutfordringen og 1001-kategoriene og slikt i samme oversikt.

Så slo det meg at det kunne vært kjekt å ha hele 1001-lista i regnearksform også, så jeg laget en ny fane for det, og kopierte lista som Elida har vedlikeholdt inn i det. Men poenget med regneark er jo å ha data i forskjellige kolonner, så her måtte det litt redigering til. Først lagde jeg en egen kolonne for årstall (utgivelsesår). Den oppdaterte jeg manuelt, noe som tok litt tid, men ikke urimelig mye sådan. Men så begynte jeg å se på å splitte ut resten av informasjonen og ta f.eks. «Javier Marias – Your Face Tomorrow (2004) *» og splitte ut «Javier Marias» i én kolonne og «Your Face Tomorrow» i en annen og skrote resten. Man KAN selvsagt gjøre det også manuelt, men det forekom meg litt… kjedelig.

Og så kom jeg på at jeg har ventet på en anledning til å teste bruk av regexp («Regular expressions») i verktøyet vi bruker på jobb (SAS, for de som skulle finne på å lure). Så i dag har jeg testet å importere fra regnearket, mikse og trikse og spytte tilbake til regnearket igjen.

Om du er nysgjerrig på regexp og hva det er kan du lese videre, hvis ikke kan du stoppe her (jeg kommer til å dele regnearket når jeg er ferdig med det, men skal leke meg litt med tellefunksjoner og sånt først, så det blir kanskje til helga), resten av innlegget blir definitivt for de spesielt interesserte.

Kort fortalt brukes regexp til å finne igjen gitte sekvenser av tegn i en tekst. I sin aller enkleste form kan det f.eks. sjekke om «i» finnes noe sted i en tekst. Bygger man på litt kan man f.eks. sjekke om input som skal være en epostadresse følger mønsteret «noe-tekst@noe-tekst.urlsuffix» eller til å fikse formatet på en serie med telefonnummer, slik at alle er formatert «landkode-mellomrom-tre tall-mellomrom-to tall-mellomrom-tre tall». Det finnes knapt grenser for hvor kompliserte uttrykkene kan bli (og å lese andres regexp-uttrykk er ikke lett).

I mitt tilfelle ville jeg finne:

1. Tekst før » – » som kan inneholde alle vanlige bokstaver pluss mellomrom, apostrof, komma, parenteser og bindestrek.

2. Tekst etter » – » som kan inneholde det samme som 1, pluss noen flere tegn, f.eks. ! og ;, men heldigvis IKKE parenteser.

For å gjøre livet enklere for meg selv gjorde jeg først et steg som erstattet » – » midt i strengen med «#» (siden navnene inneholdt både – og mellomrom ble det vanskelig å bruke » – » som tegn for hvor strengene skulle splittes, selv om det sikkert kunne vært løst på mer finurlig – eller komplisert, om du vil – vis det også).

Og da endte jeg med:

forfatter=prxchange(‘s/^([\w . ,()»|-]+)(#)(.+)/$1/’, -1, kombo2);
tittel=prxchange(‘s/^([\w . ,()»|-]+)(#)([\w& . ,!?:»|;|-]+)([(].+)/$3/’, -1, kombo2);

Rødt er forfatternavn (parentesene forteller programmet at dette er en enhet, og det er denne enheten $1 refererer til), så kommer blå # (som altså erstattet » – » mellom forfatter og tittel), grønn er tittel og oransje er «resten av strengen». Hadde titlene inneholdt parenteser ville jeg fått problemer med å skille grønn og oransje, men det var det heldigvis ingen som gjorde.

([\w . ,()»|-]+) betyr:

( ) avgrenser enheten
[ ]+ sier at det skal finnes ett eller flere tegn som stemmer med det som er inne i [ ]
\w er alle «vanlige teksttegn», både tall og bokstaver, pluss _
.,() sier at strengen også kan inneholde disse fire
» er egentlig ‘, som i Shi Nai’an, men fordi ‘ har en spesiell rolle i programmet må man skrive to fnutter etter hverandre: »
|- betyr bindestrek, bindestrek har nemlig også en egen rolle

Jeg begynte egentlig med A-z i stedet for \w, men da fant ikke programmet strengene som inneholdt ø og ë og sånt. Etter litt hjelp fra forskjellige folk på Twitter fant jeg ut at A-å virket, og tok med ø og ö, men ikke ë (som tydeligvis kommer lenger ut i rekka). Jeg fikk noen andre idéer også, som skal testes ved leilighet, men siden \w løste problemet i denne sammenhengen gikk jeg for den enn så lenge.

Jeg kunne sikkert også lagt på en «aarstall=…» om jeg ikke allerede hadde fikset den delen manuelt.

Den eneste raden jeg sto igjen med til slutt var «Georges Perec – A Void/Avoid (1969)». Hadde det vært snakk om en ny automatisert datalast hadde jeg måttet finne ut av «/» også, og det kan vel tenkes jeg faktisk prøver, men for å komme videre med regnearket har jeg bare fikset den ene raden manuelt.

Men bortsett fra Perec hadde jeg plutselig, helt automagisk, to kolonner som inneholdt forfatter og tittel for alle de 1311 linjene. Det er ganske gøy, synes jeg.

4 kommentarer om “Regneark og regexp

  1. Eg datt heilt av mot slutten då rekneark aldri har vore mi sterke side (dårlige minner frå økonomitimene på vgs), men eg liker måten du gjer det på. Det som er så flott med fleire bokbloggere er at sjølv om me har bøker til felles noterer me så ulikt og finner glede i ulike ting. Som du i dette innlegget og meg i vedlikehald av 1001-lista 🙂

    Ha ein fin kveld!

    1. Det aller meste i denne posten er vel for spesielt interesserte. Men ja, det er jo det som er så fint, at vi er forskjellige, men likevel kan ha glede av å diskutere bøker og utveksle informasjon.

  2. For those playing along at home. Jeg lekte litt videre i dag for å teste de forskjellige forslagene jeg fikk på Twitter:

    A-ø funker, men tar ikke med ü fra dette datagrunnlaget, men hvis jeg endrer til A-ü fungerer det, altså gjelds det bare å finne ut hvor langt «ut» i ascii/unicode-indexen man må.

    Men en mye ryddigere sluttløsning:
    forfatter=prxchange(‘s/(.*) – (.*) \((.*)\).*/$1/’, -1, kombo);
    tittel=prxchange(‘s/(.*) – (.*) \((.*)\).*/$2/’, -1, kombo);
    aarstall=prxchange(‘s/(.*) – (.*) \((.*)\).*/$3/’, -1, kombo);

    Siden alle linjene har enstydig format med forfatter – tittel (årstall) funker et generelt mønster når jeg bare husket å matche HELE strengen slik at prxchange ikke lot det ligge igjen noe restsøppel. Fortsatt ville det vil blitt problem dersom noen av titlene inneholdt () (og jeg har ikke testet på tittel med \, men det antar jeg egentlig går greit?).

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *

Dette nettstedet bruker Akismet for å redusere spam. Lær om hvordan dine kommentar-data prosesseres.