Portál AbcLinuxu, 8. května 2025 10:55
:/nějaká/cesta/soubor.abc
. Potřebuji capture na část nějaká/cesta/soubor.abc
. Problém je, že jednoduchý regex mi pak matchne v řetězci return ":/nějaká/cesta"; const char *a = ".txt";
část ":/nějaká/cesta"; const char *a = ".txt
, což je špatně. Musím to tedy udělat přísněji. Cesta je buď v dvojitých uvozovkách, v jednoduchých uvozovkách, v html/xml tagu nebo v css v závorkách (např. url(:/bla/bla.abc)
). A to je problém. Chtěl bych to mít jako jeden regex, kde by to bylo zkombinované. Nějak bych to nakombinoval s or operací, ale pak bych měl třeba na ":/moje/cesta.abc&t;/tag>
match, což také nechci.
Nejdále jsem se dostal k regexu (["']:\/|>\s*?:\/|\(:)(.*?)(["']|\s*?<|\))
(můžete vyzkoušet třeba na regex101.com). Jenže to matchuje i to, co nechci.
":/moje/cesta.abc" ':/moje/cesta.abc' <url>:/moje/cesta.abc</url> <bla><a>:/moje/cesta1.abc<b>:/moje/cesta2.abc</bla> neco: url(:/moje/cesta.abc) ":/moje/cesta.abc' // nechci match <url>:/moje/cesta.abc' // nechci match
Tak je lze pojmenovat. Navíc pravděpodobně půjde regexp složit s řetězců. Tak můžete napsat obdobu následujícího Perl one-lineru:
perl -nE ' BEGIN { my $cesta = ":(?<cesta>.*?)"; our $rx= join "|", map {sprintf $_, $cesta} (q{"%s"}, q{\'%s\'}, q{>%s<}, q{\(%s\)}); say $rx }; say $+{cesta} while /$rx/g ' /tmp/pom.txt
":(?<cesta>.*?)"|':(?<cesta>.*?)'|>:(?<cesta>.*?)<|\(:(?<cesta>.*?)\) /moje/cesta.abc /moje/cesta.abc ...
$cesta = ":(?<cesta>.*?)"; @maska=qw{ "cesta" 'cesta' >cesta< \(cesta\) }; s/cesta/$cesta/ foreach @maska; $rx= join "|", @maska;
":/moje/cesta.abc' <url>:/moje/cesta.abc'
<url>:/cest/a)
:/
a ostatní jsou prázdné. Ale je to pokrok, děkuji.
((["'])|[>\(]):\/(.*?)(\2|[<\)])Přínosem v řešení je dekompozice stop-tokenů od match-textu. Tím vznikne kratší zápis, který je i přehlednější. Čímž neříkám, že původní zápis byl špatný. Nuže, posuďte teď můj. Bye.
\2
teď vidím poprvé, netušil jsem, že něco takového jde.
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.