ugrás a tartalomhoz

Regex illeszkedés túl mohó

inf · 2007. Aug. 17. (P), 17.23
Sziasztok

Regexel akadtam el egy template vezérlő készítése közben.
A lényeg, hogy a template objectemnek megadok egy mintát, amit elsőre feldarabol a vezérlők elhelyezkedése szerint, majd végigmegy a tömbön, és kiszedi a vezérlőket, helyükre pedig vagy .*ot vagy a vezérlő belsejében megadott regex kódot illeszti

kb így néz ki az egész:
var a=new Template("ez egy szám: </szam:[\\d]+/>")
ebből csinál olyat, hogy
["ez egy szám: ","</szam:[\\d]+>"]
na most ezt nyilván itt egy global flages regexel szedem szét
utána végigmegyek egy nem global flagessel, és azzal kapom szét a vezérlőt, vagy ha nem vezérlő, akkor escapelem, hogy ne zavarjon be majd regex gyártásnál.

a vezérlőből csinálok egy olyat, hogy
["szam","[\\d]+"]
majd hozzáírom a készülő regex forrásához a második részt, szóval a regex forrása, ami a minta alapján készült így néz ki:
"ez egy szám: ([\\d]+)"
szóval a "szam" hoz tartozó regexet beraktam egy capturing groupba, és ha ráillesztem ezek után egy stringre, akkor a backreference[1]ből tudom majd kinyerni.

tehát a végeredmény mondjuk ennél a stringnél:
"ez egy szám: 24"
"24" lesz a backreference[1]en, amit majd egy objectben adok vissza így:
{szam:"24"}
a problémám ezzel az egésszel annyi, hogy ha a vezérlőben megadott regex kódban is van capturing group, és nem csak egy vezérlő van, akkor eltolódik a backreference sorrendje, és más adatok fognak bekerülni a végén az objectbe, ami nem túl jó.. szóval szűrni szeretném a capturing groupos regexel rendelkező vezérlőket, vagy ha nem megy, akkor replaceelem a ( eket (?: ra

a másik gondom, hogy a vezérlőket kinyerő regex mohó, tehát ha ilyet írok, hogy
"</vmi/>/>/>"
akkor az egészet vezérlőnek veszi, nekem meg arra van szükségem, hogy az első /> nél lezárja a vezérlőt, tehát hogy ne legyen mohó a regex, és sajnos nem tudom, hogy hogy tudnám ezt elérni, mert mondjuk egy karakternél elég egy szimpla [^}]* több karakternél viszont így nem lehet megoldani az egymásutániságot

ismerek még olyat, hogy negative lookahead, amivel meg lehet oldani, a capturing group szűrést elméletileg így:
/\((?!\?[:=!])/
viszont ezt nem tudom, hogy hogy építsem be a kódomba

a mostani regexem így néz ki:
/<\/([\w$]+)\s*:?\s*(.*)?\/>/
ha valaki tud segíteni, vagy tanácsot adni, azt szívesen fogadom.

Üdv.
Laci

szerk:
annyi fejlemény van a témában, hogy a mohóságot közben megtudtam, hogy a * és + utáni ?el lehet levenni, viszont sokat nem segített a dolog, mert </vmi/>/>/> helyett most </vmi/>/>-t fog el a regex, ami még szintén nem jó :-/
 
1

Lusta kvantorok

Török Gábor · 2007. Aug. 18. (Szo), 07.06
Az alapján, amit sikerült kihámoznom:
  • hogy a referenciáid ne tolódjanak el, ahogy írtad is, használd a csak csoportosító zárójeleket (?:
  • a legkisebb illeszkedéshez pedig amit végül írtál, valóban az a megoldás, lusta kvantorokat *? +? kell használnod.

A példa regexed /<\/([\w$]+)\s*:?\s*(.*)?\/>/ nálam úgy illeszkedik a </vmi/>/>/> kifejezésre, ahogy azt te szeretnéd, csak az első /> karakter csoportig "megy el".
2

Hozzászólás témája:

inf · 2007. Aug. 18. (Szo), 08.44
Szia!

Aha, akkor nálam volt a probléma, mert nálam elment a másodikig, pedig lustán volt. Kipróbálom újra, hátha valamit elírtam.

Én nyilván csak csoportosító zárójelezést használok, csak ez egy js frameworkben lesz benne, szóval kéne valami debug olyan esetre, ha valaki nem csoportosító zárójelet használ, de azt meg fogom oldani replaceszel.

Kicsit átgondoltam, és módosítottam a szerkezeten kicsit praktikusabbra:

</vmi(regex)/>
Így nem kell a két zárójelet külön kirakni.
A regex hozzá pedig:

/<\/([\w$]+)\s*(?:\(\s*(.*?)\))?\/>/
ami szerintem jó, de a gyakorlat sajnos mást mutat, és keine Ahnung, hogy mi a baja :-/

szerk:
Sikerült működésre bírni, az volt a gondja, hogy ékezetes szöveget adtam neki, és "í" neki nem word karakter.. Köszi a segítséget!