konkretni problem regexp (sed)

Michal Kubecek mike na mk-sys.cz
Sobota Červen 7 18:46:57 CEST 2003


On Sat, Jun 07, 2003 at 04:34:49PM +0200, Michal Bozon wrote:
> Zdravim.
> 
> Mam nasledujici problem se sed, mozna ze neco spatne chapu, ale...
> Modelovy pripad:
> chci vyextrahovat prvni souvislou radu cisel z retezce, napriklad
> "as-dff42583f_sd" -> "42583"
> 
> $ echo "as-dff42583f_sd" | sed 's/.*\([0-9]\+\).*/\1/'
> 3
> 
> napravit to jde takhle:
> 
> $ echo "as-dff42583f_sd" | sed 's/.*[^0-9]\([0-9]\+\).*/\1/'
> 42583
> 
> Proc nedostanu stejny vysledek i v prvnim propade? Jedna se pri
> vyhodnocovani .* a [0-9]\+ k nejakemu stretu zajmu? Existuje jistejsi
> zpusob reseni meho problemu?

Protože v prvním případě to opravdu není jednoznačné: vy si sice
představujete, že úvodní '.*' reprezentuje 'as-dff', ale ono to zrovna tak
dobře může být tak, že '.*' -> 'as-dff4258' a a '[0-9]+' -> '3'.
Pokud si dobře vzpomínám, v případě nejednoznačnosti má přednost ta část,
která je dřív, v tomto případě '.*'. Ve druhém případě už jste
nejednoznačnost vyloučil, takže sed nemá na výběr.

Ale neradujte se, správné řešení to také není. Protože pokud je posloupnost
číslic hned na začátku, váš druhý příklad ji nenajde. Zkuste si třeba
'123as-dff42583f_sd': váš příkaz ukáže '42583'. Lepší by bylo

echo "123as-dff42583f_sd" | sed 's/[^0-9]*\([0-9]\+\).*/\1/'

                                                           Michal Kubeček


Další informace o konferenci Linux