Portál AbcLinuxu, 19. dubna 2024 23:37


Dotaz: Regex na cestu k souboru v xml/cpp

18.4.2017 20:37 דניאל | blog: godismyjudge
Regex na cestu k souboru v xml/cpp
Přečteno: 452×
Odpovědět | Admin
Potŕeboval bych poradit s regexem. Potřebuji v Qt, pomocí QRegularExpression, udělat regex, který mi v souborech najde řetězce, které jsou cesty "resource souborů" v Qt. Taková cesta má formát :/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
Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

18.4.2017 20:42 Kit | skóre: 45 | Brno
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp
Odpovědět | | Sbalit | Link | Blokovat | Admin
Zkus s tím souborem pracovat jako s XML - tyto problémy odpadnou.
Komentáře označují místa, kde programátor udělal chybu nebo něco nedodělal.
19.4.2017 05:58 דניאל | blog: godismyjudge
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp
Neodpadnou. Jsou to soubory vícero typů (xml/ui, cpp a css), snažím se o regex, který je obslouží všechny (protože v cpp stejně můžu mít kus css či xml/html jako řetězec), pokud možno s co nejméně falešnými výsledky. Ten regex, co jsem napsal, to více méně zvládne, ale je takový ošklivý, jestli by nešel zjednodušit. Ty poslední 2 matche, které nejsou chtěné, zatím tak hrozně nevadí, ale bylo by lepší, kdyby nebyly.
19.4.2017 07:50 NN
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp
Puzil bych negativni lookahead. Nekdy je lepsi hledat podminku ktera "nevyhovuje".
19.4.2017 09:03 ramlok0
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp
Odpovědět | | Sbalit | Link | Blokovat | Admin
hledas 4 specificke podminky - zacatek/konce matche - tohle funguje:

(["]:\/)(.*?)(["])|([']:\/)(.*?)(['])|([>]:\/)(.*?)([<])|([(]:\/)(.*?)([)])
19.4.2017 19:17 דניאל | blog: godismyjudge
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp
Ano, matche jsou správné, ale zase tam je problém, že capture group pro tu cestu je pokaždé jiná.
wamba avatar 19.4.2017 20:29 wamba | skóre: 38 | blog: wamba
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp

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
...
This would have been so hard to fix when you don't know that there is in fact an easy fix.
20.4.2017 19:01 דניאל | blog: godismyjudge
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp
Když tam ale mám stejné názvy, dostávám chybu "A subpattern name must be unique" :-(
wamba avatar 20.4.2017 19:41 wamba | skóre: 38 | blog: wamba
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp
v Perlu to funguje, tak je třeba odzkoušet jestli to nefunguje i v Qt a nespoléhat se na implementaci na https://regex101.com/
This would have been so hard to fix when you don't know that there is in fact an easy fix.
21.4.2017 13:01 RM
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp
Já, pokud má být cílem minimalizovat nečitelnost (reg. výrazu), bych ty dva řádky napsal takhle (já ten sprintf nemusim;):
    $cesta = ":(?<cesta>.*?)";
    @maska=qw{ "cesta" 'cesta' >cesta< \(cesta\) };
    s/cesta/$cesta/ foreach @maska;
    $rx= join "|", @maska;
20.4.2017 15:02 ramlok0
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp
Ok, opraveno, ted je capture group vzdy stejna. ((["'])|(>)?|(\()?):\/(.*?)(\1|(?(1)<)|(?(1)\)))
20.4.2017 18:58 דניאל | blog: godismyjudge
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp
Teď to ale matchuje ty 2, které nechci, a naopak ty, co chci, to nematchuje. No asi to nebude tak jednoduché, jak jsem si myslel.
":/moje/cesta.abc'
<url>:/moje/cesta.abc'
20.4.2017 19:38 ramlok0
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp
Hm, me to funguje, nemas extra mezeru za posledni zavorkou?
wamba avatar 20.4.2017 20:08 wamba | skóre: 38 | blog: wamba
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp
u mě to taky funguje, ale selže to při: <url>:/cest/a)
This would have been so hard to fix when you don't know that there is in fact an easy fix.
21.4.2017 19:33 דניאל | blog: godismyjudge
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp
Opravdu to byla mezera na konci, omlouvám se. Teď je stále na těch 2 posledních ale match, s tím, že group 0 je :/ a ostatní jsou prázdné. Ale je to pokrok, děkuji.
20.4.2017 20:03 Charon
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp
OK, zkusil jsem pro Vás inovaci REGEX od RAMLOK.
((["'])|[>\(]):\/(.*?)(\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.
21.4.2017 19:41 דניאל | blog: godismyjudge
Rozbalit Rozbalit vše Re: Regex na cestu k souboru v xml/cpp
Tohle vypadá opravdu dobře, asi ho použiju. Regexem to asi lépe nepůjde a bez plnohodnotných parserů prostě nechtěný match bude moci nastat. To s tou \2 teď vidím poprvé, netušil jsem, že něco takového jde.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.