RE a utf-8

Pavel Smerk xsmerk na fi.muni.cz
Čtvrtek Září 4 11:28:46 CEST 2014


On Thu, Sep 04, 2014 at 09:49:14AM +0200, Jiří Václavík wrote:
> Ahoj,
> 
> podle debugu regularnich vyrazu to cele selze uz v optimalizacni fazi, kdy
> se matchuji pevne retezce, viz:
> 
> echo AB:pán | perl -CSAD -Mutf8 -Mre=debugcolor -ne 'print if /AB:.*án$/'
> Compiling REx "AB:.*%x{e1}n$"
> Final program:
>    1: EXACT <AB:> (3)
>    3: STAR (5)
>    4:   REG_ANY (0)
>    5: EXACT <\x{e1}n> (7)
>    7: EOL (8)
>    8: END (0)
> anchored utf8 "AB:" at 0 floating utf8 "%x{e1}n"$ at 3..2147483647
> (checking anchored) minlen 5
> Guessing start of match in sv for REx "AB:.*%x{e1}n$" against
> "AB:p%x{e1}n%n"
> UTF-8 pattern and string...
> Found anchored substr "AB:" at offset 0...
> Contradicts floating substr "%x{e1}n"$, giving up...
> Match rejected by optimizer
> Freeing REx: "AB:.*%x{e1}n$"
> 
> To n na konci "%x{e1}n" je nejake divne. Clovek nikdy nevi, co za retezec
> nakonec dorazi, tak se na to podivejme:
> 
> echo 'AB:pán' | perl -ne 'print join " ", map{ord} split m{}xms'
> 65 66 58 112 195 161 110 10
> 
> Ha, vypada to, ze je tam LINEFEED navic. Takze problem neni v perlu, ale v
> prikazu echo, ktery ho tam automaticky prida, kdyz neni volan s volbou -n
> :-)

Na \n by ale nemělo být nic špatného, ne? Prostě se má namatchovat na $, což
se ve většině případů taky správně stane.

Zřejmě to nefunguje, když pracujeme s unicode znaky, pro přirozená n, m je

A = jednoznačný řetězec délky n + m libovolných znaků
B = libovolný řetězec libovolných znaků, třeba i prázdný
C = jednoznačný řetězec délky n libovolných znaků začínající neASCII7 znakem

a matchujeme ABC\n proti /A.*C$/, naopak to bude fungovat, pokud budeme
matchovat jen ABC nebo proti /A.*C$/m, /^A.*C$/ ap.

Pokud mi ten popis ještě někdo nerozšíří či nezúží, asi se tedy pokusím
vygenerovat nějaký bugreport nebo co. :-)

Obecněji se zdá, že problematická je konfigurace regulárního výrazu /A'B'C'$/

A' = regulární výraz s pevnou délkou obsahující jednoznačný řetězec délky n+1
B' = libovolný RE jemuž mohou odpovídat řetězce alespoň dvou různých délek
C' = jednoznačný řetězec délky n libovolných znaků začínající neASCII7 znakem

ale to už jsem moc nezkoušel a pro odhalení chyby to asi nebude podstatné.

							Díky,		P.

> Dne 4. září 2014 8:49 Jan Kasprzak <kas na fi.muni.cz> napsal(a):
> 
> > Pavel Smerk wrote:
> > :       Ahoj vespolek,
> > :
> > : asi mám nějaké zatmění mysli: proč druhý příkaz nic nevypíše? Stejně tak
> > se
> > : to chová i v perl 5.10, naopak novější nemám k dispozici.
> >
> >         5.8 a 5.18 se chová stejně. Na locale by to nemělo záviset, pokud
> > nedáš
> > -Mlocale (i s LC_ALL=C se to chová stejně). Ještě jsem ověřil, že se to
> > chová
> > stejně divně i pro jiné kategorie znaků:
> >
> > $ echo AB:p???n | perl -Mutf8 -CSAD -ne 'print if /AB:.*???n$/'
> >
> > kromě ascii, ovšem:
> >
> > $ echo AB:pan | perl -Mutf8 -CSAD -ne 'print if /AB:.*an$/'
> > AB:pan
> >
> > a že součástí problému může být struktura toho RE:
> >
> > $ echo AB:pán | perl -Mutf8 -CSAD -ne 'print if /AB[:x].*án$/'
> > AB:pán
> > $ echo AB:pán | perl -Mutf8 -CSAD -ne 'print if /A[BC]:.*án$/'
> > AB:pán
> >
> > naopak v -Mutf8 -CSAD problém není - když to nahradím za use utf8 a
> > podobně,
> > tak se to chová stejně.
> >
> >         Moc jsem nepomohl, sorry.
> >
> > -Y.
> >
> > --
> > | Jan "Yenya" Kasprzak   <kas at {fi.muni.cz - work | yenya.net -
> > private}> |
> > | New GPG 4096R/A45477D5 -- see
> > http://www.fi.muni.cz/~kas/pgp-rollover.txt |
> > | http://www.fi.muni.cz/~kas/     Journal:
> > http://www.fi.muni.cz/~kas/blog/ |
> > Hatsune Miku: the only girl that can have a leek in a song called "Bad
> > Apple"
> > _______________________________________________
> > Perl mailing list
> > Perl na mailman.muni.cz
> > https://mailman.muni.cz/mailman/listinfo/perl
> >


Další informace o konferenci Perl