Egy másik topikban szó volt arról, bizonyos napokat színezni kellene a cal parancs kimenetében. Erre gyorsan összetákoltam egy nem igazán általános, de jó megoldást, viszont a saját scriptemet sem értem egészen, pontosabban az egyik regexpet.A cal kimenete nálam így néz ki:
August 2013
Su Mo Tu We Th Fr Sa
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
A fejléc figyelmen kívül hagyásához írtam egy ilyen regexpet:
/^ *[^[:digit:] ]/
Viszont eredetileg így akartam, csak ez nem működött jól:
/^ *[^[:digit:]]/
Az elképzelés az, hogy sor elejét követően vagy létező, vagy nem létező szóközök után amennyiben nem szám karakter jön, akkor illeszkedik a regexpre a minta, s kihagyom a színezést. Az akció része most nem érdekes.
Úgy látom, a második változatom illeszkedik arra az esetre, amikor szóközöket követően szám karakter jön. Ez egy nyakatekert értelmezésben persze lehet:
illeszkedik a sor elejére, illeszkedik valahány, de nem az összes szóközre - például nulla darabra -, majd a szóközre, amely valóban nem szám karakter.
Az a kérdésem, hogy a / */
a leghosszabb, vagy a legrövidebb olyan szakaszra illeszkedik, amelyre tud illeszkedni?
GNU Awk 4.0.2
amiről szó van.
- 4329 megtekintés
Hozzászólások
"illeszkedik a sor elejére, illeszkedik valahány, de nem az összes szóközre - például nulla darabra -, majd a szóközre, amely valóban nem szám karakter."
Úgy látszik, tényleg ez történik:
cal | perl -lne 'if (/^ *[^[:digit:]]/p) {print "[${^MATCH}][${^POSTMATCH}]"}'
(Igen, tudom, perl, de kérdés szempontjából a regex ugyanúgy viselkedik, mint awkban.)
Alapvetően egyébként a * módosító "kapzsi", azaz a lehető leghosszabb szakaszra illeszkedik.
- A hozzászóláshoz be kell jelentkezni
A POSTMATCH változó mit ad vissza? Vagy azért raktad bele, hogy áttekinthetőbb legyen a kimenet? Gondolom, a MATCH a lényeg.
Alapvetően egyébként a * módosító "kapzsi", azaz a lehető leghosszabb szakaszra illeszkedik.
Jó, de akkor itt miért nem? Kiszúrt magának, pikkel rám? :)
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
A ${^POSTMATCH} a stringnek az illeszkedő rész-string utáni részét tartalmazza, csak azért tettem bele, hogy világos legyen, melyik sorról van szó. perldoc perlvar BTW.
"Jó, de akkor itt miért nem? Kiszúrt magának, pikkel rám? :)"
Nem, éppen ellenkezőleg: szeretne mindenáron a kedvedre tenni :)
Vegyük a " 4 5 6 7 8 9 10" sort.
A " *" a lehető legtöbb szóközre szeretne illeszkedni, tehát először megnézi egyre. Utána viszont számjegy áll, tehát ezt az esetet eldobja.
Utána megnézi nulla darab szóközre (a * definíciója ezt megengedi), a következő karakter szóköz (azaz nem számjegy, ahogy írtad), tehát az egész minta illeszkedik, öröm, boldogság.
szerk:
cal | perl -mre=debug -lne 'if (/^ *[^[:digit:]]/p) {print "[${^MATCH}][${^POSTMATCH}]"}'
Így meg is magyarázza, hogy mit csinál.
- A hozzászóláshoz be kell jelentkezni
Aha, tehát másként működik, mint amit erről _gondoltam_. Valamiért azt képzeltem, hogy ha eljut valameddig, akkor oda leszúrja a pointert, s onnan nézi tovább. Ha onnan illeszkedik, akkor jó, ha nem, akkor pedig nem.
Ehelyett ez végig sakkozza az összes lehetséges megoldást, és ha van illeszkedés, akkor örül. Ha pedig sehogy sem tudja a regexpet a mintára paszírozni, akkor nincs illeszkedés.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Tudtommal a perl volt az egyetlen, amelyiknel lehetett legrovidebb illeszkedest eloirni, altalaban a regexpek a leghosszabbra illeszkednek.
- A hozzászóláshoz be kell jelentkezni
Érteni vélem - bár nem biztos -, viszont akkor a regexp szóköz csillag része miért nem az összes szóközre illeszkedik, majd az utána lévő számjegynek nem kellene illeszkednie a [^[:digit:]]
részre.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Vagy arra gondolsz, hogy az összes lehetséges esetet végignézi, s amelyik a teljes kifejezésre a lehető leghosszabb illeszkedést adja, az lesz az eredmény?
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Nem nagyon értem a kérdést. Amit én tudok regexppel kapcsolatos szabályok (és amiket szerintem neked nem kell magyaráznom, mert tudod)
- összetett regexp esetén minden résznek illeszkednie KELL - azaz "ab" minta esetén lennie kell a-nak is, b-nek is a vizsgált szövegben a találathoz (és persze közvetlenül egymás után kell álljanak)
- az első (valódi, azaz 0-nél hosszabb) találat számít, még akkor is, ha a vizsgált szövegrészen belül később lenne hosszabbb illeszkedés is. "ablak az abba lemezeire", ha a minta "ab*", akkor a kezdő pozícióban van egy 1 hosszú találat (a) meg egy 2 hosszú (ab), és hiába van hátrébb egy 3 hosszú (abb) is, az elején levő ab-re fog illeszkedni. (Viszont ha a minta alapján lehet 0 hosszú a találat, és nincs "valódi" találat, akkor a sor eleji "semmi"-re fog 0 hosszan ileszkedni - azaz lesz találat, de 0 hosszúságban - ami persze nem ugyanaz, mint a "nincs találat")
- ha ugyanabban az "első" kezdőpozícióban van többféle hosszúságú találat, a hosszabb lesz a találat. Előző példánál ezért volt az "ab" a találat az "a" helyett.
Ellenben nincs meghatározva, hogy ha a regexpől több *-os illeszkedne, akkor azok hogyan fognak illeszkedni:
szöveg: aaaaaaa
regexp: a*a* - nincs meghatározva, hogy melyik a* mennyi a-ra fog illeszkedni. (Sejtésem szerint a regexp libek többsége esetén az első a* illeszkedik 7 db a-ra, a második a* pedig 0 db-ra - de ez sejtés, és tudtommal nincs szabályozva - sőt többségében dokumentálva sem, hogy az adott verzió mit cisnál.)
- A hozzászóláshoz be kell jelentkezni
Köszönöm.
Ott tévedtem el - amit fentebb írtam -, hogy vélelmeztem, a /^ */
részben a legtöbb szóközig eljut, utána nézi azt, hogy nem szám, s mivel nekem szám jön, vélelmeztem, nem ad illeszkedést. Arra nem gondoltam, hogy a részkifejezés illeszkedése után szükség esetén visszafelé is mozgatja a pointert, ha az egész kifejezésre nézve így találhat illeszkedést. Itt ez történt. Az utolsó szóközt nem számjegyre illeszkedő karakternek nézve - /[^[:digit:]]/
-, s a /^ */
részt a lehetségesnél eggyel rövidebb részre illesztve az egész kifejezés már illeszkedni fog.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni