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