[RegEx] Match name value pair

Pagina: 1
Acties:

  • Plekuz
  • Registratie: September 2002
  • Laatst online: 02-01 15:26

Plekuz

available in strong mint

Topicstarter
Ik heb de volgende code (voorbeeld)
code:
1
PRG={FRM=A,CND={EXP="A,B",USE=0}}


Nu wil ik dit via een regex uitgesplitst hebben in
code:
1
2
3
4
5
6
7
8
9
PRG=
{
FRM=A
CND=
{
EXP="A,B"
USE=0
}
}


Ik ben al gekomen tot de regex (er kunnen meerdere regels zijn daarom \r\n\t):
code:
1
(?<=[\r\n\t{,])[^]\r\n\t[,{}]+|{|}


Dit gaat goed behalve voor het stukje tussen de quotes, dat wordt ook gebroken op de komma, waardoor ik een match krijg op EXP="A en apart een match op B". Moge duidelijk zijn dat dat niet het resultaat is wat ik wens te krijgen.

De vraag: kan ik het via regex voorelkaar krijgen om voorwaardelijk te matchen op de komma in het code lookbehind gedeelte? Dus: wel matchen als ie niet tussen quotes staat en niet matches als ie wel tussen quotes staat. BVD!

"There he goes. One of God's own prototypes. Some kind of high powered mutant never even considered for mass production. Too weird to live, and too rare to die."


  • Ibex
  • Registratie: November 2002
  • Nu online

Ibex

^^ met stom.

PHP:
1
2
3
4
5
$var = "PRG={FRM=A,CND={EXP=\"A,B\",USE=0}}";
$var = preg_replace("/PRG=\{FRM=([^,]*?),CND=\{EXP=\"([^\"]*?)\",USE=([^\}]*?)\}\}/is",
                    "PRG=\n{\nFRM=\\1\nCND=\n{\nEXP=\\2\nUSE=\\3\n}\n}",
                    $var);
echo $var; // goede code parsen

Dit zou moeten werken denk ik, ik heb het wel niet getest :). De desbetreffende regex is dus:

code:
1
/PRG=\{FRM=([^,]*?),CND=\{EXP=\"([^\"]*?)\",USE=([^\}]*?)\}\}/is

Deze is wel volgens perl synthax, maar dat kan je wellicht zelf wel omvormen, of, indien je programmeeromgeving deze synthax ondersteunt, kan je direct deze eens proberen :)

[ Voor 83% gewijzigd door Ibex op 23-06-2004 21:24 ]

Archlinux - Rode gronddingetjes zijn lekker - Komt uit .be


  • Plekuz
  • Registratie: September 2002
  • Laatst online: 02-01 15:26

Plekuz

available in strong mint

Topicstarter
Hey bedankt Ibex! Alleen ga ik een beetje vervelend antwoord geven: de voorbeeldcode die ik gaf is echt maar een voorbeeld, er staat daar nu wel PRG en CND enzo, maar het kan ook nog heel veel anders zijn ook nog meer tekens en meer name-value pairs en nog meer haakjes, zoals (wederom voorbeeld)

code:
1
HDR={TOTAL={GET=5,TEXT="A,B",FNT={TYPE=3,SIZE=12},BCK="Red"}},DIR="C:\"


Toch erg bedankt voor je moeite!

[ Voor 6% gewijzigd door Plekuz op 24-06-2004 09:50 ]

"There he goes. One of God's own prototypes. Some kind of high powered mutant never even considered for mass production. Too weird to live, and too rare to die."


Verwijderd

Ik weet niet in wat voor taal je de oplossing wilde hebben, maar dit is _een_ (waarschijnlijk te zware) oplossing in php:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function storeStrings($string, &$array)
{
    $array[] = $string;
    return '%s';
}

$string = 'PRG={FRM=A,CND={EXP="A,B",USE=0}}';
$storedStrings  = array();
$string = preg_replace('/((["\']).*?\\2|%s)/se', 'storeStrings("\\1", $storedStrings)', $string);

$s  = array(    '/\s*([\{\}])\s*/i',
                '/\s*,\s*/s',
                '/\n\n/s',
        );
$r  = array(    "\n\\1\n",
                "\n",
                "\n",
        );

$string = vsprintf(preg_replace($s, $r, $string), $storedStrings);

  • Plekuz
  • Registratie: September 2002
  • Laatst online: 02-01 15:26

Plekuz

available in strong mint

Topicstarter
Thanks Takkie! De taal wordt hoogstwaarschijnlijk Delphi 8 of C#, maar PHP kan ik ook wel lezen hoor. Je geeft me in ieder geval weer genoeg ideeen om mee aan de slag te gaan.

"There he goes. One of God's own prototypes. Some kind of high powered mutant never even considered for mass production. Too weird to live, and too rare to die."


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 08:54

crisp

Devver

Pixelated

Het probleem van nesting kan je met een stukje recursie oplossen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
$s = 'PRG={FRM=A,CND={EXP="A,B",USE=0}}';

$o = preg_replace_callback('/{(([^{}]*|(?R))*)}/', 'cb', $s);

echo '<pre>'.$o.'</pre>';

function cb($matches) {

  $matches[1] = preg_replace_callback('/{(([^{}]*|(?R))*)}/', 'cb', $matches[1]);

  return "\n{\n".$matches[1]."\n}";

}


Ik weet niet of Delphi of C# ook recursie in regexpen ondersteunen, anders denk ik dat je beter een soort van tokenizer kan gebruiken.

Intentionally left blank


Verwijderd

crisp schreef op 24 juni 2004 @ 23:42:
Het probleem van nesting kan je met een stukje recursie oplossen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
$s = 'PRG={FRM=A,CND={EXP="A,B",USE=0}}';

$o = preg_replace_callback('/{(([^{}]*|(?R))*)}/', 'cb', $s);

echo '<pre>'.$o.'</pre>';

function cb($matches) {

  $matches[1] = preg_replace_callback('/{(([^{}]*|(?R))*)}/', 'cb', $matches[1]);

  return "\n{\n".$matches[1]."\n}";

}


Ik weet niet of Delphi of C# ook recursie in regexpen ondersteunen, anders denk ik dat je beter een soort van tokenizer kan gebruiken.
Hmm die Recursive Pattern oplossing (?R) kende ik nog niet, nice! :P Maar als er nu in een string een { of } zit heb je natuurlijk wel een probleem, tenzij dat per definitie al niet voorkomt ;)

  • Plekuz
  • Registratie: September 2002
  • Laatst online: 02-01 15:26

Plekuz

available in strong mint

Topicstarter
Verwijderd schreef op 25 juni 2004 @ 08:55:
[...]


Hmm die Recursive Pattern oplossing (?R) kende ik nog niet, nice! :P Maar als er nu in een string een { of } zit heb je natuurlijk wel een probleem, tenzij dat per definitie al niet voorkomt ;)
Hmm, goede opmerking wat betreft de kans op { of } tussen de quotes. Zelf nog niet aan gedacht :X

"There he goes. One of God's own prototypes. Some kind of high powered mutant never even considered for mass production. Too weird to live, and too rare to die."


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 08:54

crisp

Devver

Pixelated

Weakling schreef op 25 juni 2004 @ 11:43:
[...]


Hmm, goede opmerking wat betreft de kans op { of } tussen de quotes. Zelf nog niet aan gedacht :X
Daarom is een tokenizer voor dit soort zaken gewoon veel handiger, je kan dan bijvoorbeeld als rule opgeven dat hij na een " alle { en } moet negeren tot aan de volgende "
Daarbij is het ws zelfs sneller; reguliere expressies zijn niet altijd zaligmakend.

Intentionally left blank

Pagina: 1