I grep och flera andra UNIX-program används något som kallas för reguljära mönster. Syftet med reguljära mönster är helt enkelt att matcha text. Tekniken liknar den som skalet använder för att matcha filnamn, men den är mycket kraftfullare. De följande sidorna beskriver hur reguljära mönster byggs upp.
Reguljära mönster kan innehålla flera symboler,
metatecken, som har speciella betydelser.
Metatecknen är . \ * [ ^ och $.
Det enklaste av dem är punkten.
Den matchar ett godtyckligt tecken.
(Dock med undantag för nyrad-tecknet.
Då grep och andra program
som använder reguljära mönster endast
betraktar en rad i taget,
kan mönstren aldrig innehålla något nyrad-tecken.)$ grep 'n.ta' bellman
den skönsta nymf, som åt dig ler,
inunder armen tag.
$Mönstret n.ta matchade här ''nsta'' och ''n ta''.
Om mönstret innehåller flera punkter så matchar varje
punkt ett godtyckligt tecken; det behöver inte vara samma
tecken varje gång:$ grep 'n..a' bellman
från Bacchi buller och tumult,
och du, du yngling, lyd min lag:
den skönsta nymf, som åt dig ler,
inunder armen tag.
$Genast undrar man hur man ska kunna matcha en punkt.
Svaret är att såväl punkten som de övriga metatecknen skyddas av
det bakvända snedstrecket:$ grep 'tag\.' bellman
inunder armen tag.
$Om vi utelämnar skyddet för punkten, så matchar den
bla blanktecken:$ grep 'tag.' bellman
inunder armen tag.
nå välan, så tag dig då en sup,
tag dig se'n dito en, dito två, dito tre,
$Mycket ofta måste man skydda reguljära
mönster eftersom de kan innehålla
symboler som har en speciell betydelse för skalet.
Tex måste mönstret tag\. skyddas för att
skalet inte ska plocka bort det bakvända snedstrecket.
Vi kommer därför konsekvent att använda apostrofer
som beskydd för mönstret,
även när det som i fallen n..a och
tag. ovan inte är strängt nödvändigt.
Om vi vill matcha en apostrof tvingas vi dock göra så här:$ grep \' bellman
tag dig se'n dito en, dito två, dito tre,
$
Reguljära mönster använder hakparenteser för att matcha en lista
av tecken. Lyckligtvis är syntaxen densamma som för
motsvarande jokertecken i skalet.
Mönstret [A-J] matchar alltså en av versalerna från A till J.$ grep '[A-J]' bellman
från Bacchi buller och tumult,
när döden ropar: Granne, kom,
Du gubbe, fäll din krycka ner,
$Nästa uppgift är att finna de rader i filen bellman
som innehåller någon stor bokstav. Detta är lätt,
vi kan helt enkelt använda mönstret [A-ZÅÄÖ].
Men det finns ett bättre sätt att ange alla stora bokstäver,
nämligen [:upper:].
(I tabell
ges en förteckning över
de kategorier av tecken som kan anges på liknande sätt.)
Om man sätter tecknet ^ direkt efter den vänstra
hakparentesen, så matchas ett godtyckligt
tecken som inte räknas upp i listan.
Så här finner vi de rader som innehåller texten ''du''
följt av något annat än kommatecken:$ grep 'du[^,]' bellman
och du, du yngling, lyd min lag:
så dör du nöjdare.
$Bara den första raden i filen bellman saknar såväl
punkt som kommatecken:$ grep -v '[.,]' bellman
Så lunka vi så småningom
$
Den minsta beståndsdelen i reguljära mönster,
som vi kan kalla för en ''atom'',
matchar exakt ett tecken.
Vi har redan beskrivit atomerna.
Tabell
ger en sammanfattning av dem.
|
.
Metatecknen $ och ^ matchar
början respektive slutet av en rad.
Så här finner vi alltså de rader som inleds
med ''och'':$ grep '^och' bellman lenngren
^ förankrar
mönstret till början av en rad.
Analogt förankrar dollartecknet ett mönster till
slutet av en rad.
Vilka rader slutar med tecknen ''an''?$ grep 'an$' bellman lenngren
bellman:från Bacchi buller och tumult,
lenngren:med klunk för klunk och bit för bit,
|
\< matchar början av ett ord.
Så här söker vi efter ord som börjar på ''dit'':$ grep '\<dit' bellman
Efter en atom kan man placera en ''multiplikator'', som
upprepar atomen ett antal gånger.
En förteckning av multiplikatorerna ges i
tabell
.
Metatecknet * betyder
att föregående atom får upprepas
hur många gånger som helst (inklusive noll).$ grep 'ul*t' bellman lenngren
bellman:från Bacchi buller och tumult,
bellman: ditt timglas är nu fullt.
lenngren:matt utstäckt mellan tvenne lakan.
$Mönstret ul*t matchade såväl ''ult'' som
''ullt'' och ''ut''.$ grep o.*st lenngren
Vår prost jag häromdagen såg
sig hävde upp mot isterhakan.
sin frukost redan färdig fann
$Mönstret o.*st matchade här ''ost'' och ''ot ist''.
Lägg märke till att .* matchar en godtycklig följd av tecken.
Vilka av de rader som innehåller
texten ''in'' slutar med ett kommatecken?$ grep 'in.*,$' bellman
Du gubbe, fäll din krycka ner,
$Vilka ord börjar med d och slutar med n?$ grep '\<d[[:alpha:]]*n\>' bellman
när döden ropar: Granne, kom,
Du gubbe, fäll din krycka ner,
den skönsta nymf, som åt dig ler,
$De ord som gav träff ovan var ''döden'', ''din'' och ''den''.
Multiplikatorn \? upprepar föregående atom noll eller
en gång:$ grep 'ul\?t' bellman lenngren
bellman:från Bacchi buller och tumult,
lenngren:matt utstäckt mellan tvenne lakan.
$Multiplikatorn \+ upprepar föregående atom en eller
fler gånger:$ grep 'ul\+t' bellman lenngren
bellman:från Bacchi buller och tumult,
bellman: ditt timglas är nu fullt.
$
Nu ska vi leta efter en följd av
små bokstäver som omges av ett ''n'' och ett ''e'':$ grep 'n[[:lower:]]*e' bellman
när döden ropar: Granne, kom,
Du gubbe, fäll din krycka ner,
inunder armen tag.
så dör du nöjdare.
$
|
\{ och \} ange
exakt hur många gånger atomen får upprepas.
Texten ''nunde'' ur ordet ''inunder'' består
av ett ''n'' följt av tre små bokstäver och ett ''e'':$ grep 'n[[:lower:]]\{3\}e' bellman
när döden ropar: Granne, kom,
Du gubbe, fäll din krycka ner,
när döden ropar: Granne, kom,
|
\|.
Det lodräta strecket \| betyder ''eller'', så
det totala mönstret matchar de textsträngar som matchas av något av
de alternativa mönstren.
Så här finner vi de rader som innehåller något av orden
''du'', ''dig'' eller ''ditt'':$ grep 'du\|dig\|ditt' bellman
och du, du yngling, lyd min lag:
den skönsta nymf, som åt dig ler,
Tycker du, att graven är för djup,
nå välan, så tag dig då en sup,
tag dig se'n dito en, dito två, dito tre,
\( och \).$ grep '\(du\|dig\|ditt\).*\<är\>' bellman
Tycker du, att graven är för djup,
Ett reguljärt mönster som omges av
tecknen \( och tecknen \)
kan behandlas som en atom. Därigenom blir
det möjligt att placera en multiplikator på mönstret.$ grep '\(du,\? \)\{2,\}' bellman
och du, du yngling, lyd min lag:
$
Den text som matchas av ett mönster
som omges av \( och \), sparas i ett så
kallat register. Man kan referera till texten
i registret med tecknen \1.
Så här finner vi de fall då a, b eller c
förekommer två gånger i rad:$ grep '\([abc]\)\1' bellman
från Bacchi buller och tumult,
Du gubbe, fäll din krycka ner,
$Ovan fick vi träff på ''cc'' i ordet ''Bacchi''
respektive ''bb'' i ordet ''gubbe''.
Finns det några ord som slutar med en dubblerad bokstav?$ grep '\([[:alpha:]]\)\1\>' bellman
ditt timglas är nu fullt.
Du gubbe, fäll din krycka ner,
Tycker du, att graven är för djup,
$Ja, ''ditt'', ''fäll'' och ''att''.
Om det förekommer flera par av tecknen \( och \)
i ett reguljärt mönster, så sparas den matchande texten i upp till
nio olika register. Den text som matchar mönstret i
parentesen längst till
vänster sparas i register 1. Register 2 hör till
parentesen näst längst till vänster osv.
Innehållet i register n matchas av \n.