[RegEx] Regular Expression Problem

02/23/2013 12:14 Cnypher#1
ERLEDIGT!

Aloha zusammen,

habe ein kleines Problem mit RegEx. Habe mich bisher leider wenig damit beschäftigt..
Nun weiß ich auch warum... vll kann mir einer von euch helfen...

Hier mal zum Aufbau:

Quelauszug der durchsucht werden muss:
PHP Code:
[{"name":"Geschmolzener Kern","normal":2,"heroic":0,"id":2717,
"bosses":[{"id":11502,"name":"Ragnaros","normalKills":2,"normalTimestamp":1341851820000}]},

{
"name":"Pechschwingenhort","normal":2,"heroic":0,"id":2677,"bosses":[{"id":11583,"name":"Nefarian","normalKills":8,"normalTimestamp":1340452489000}]},

{
"name":"Ruinen von Ahn'Qiraj","normal":2,"heroic":0,"id":3429,"bosses":
[{
"id":15339,"name":"Ossirian der Narbenlose","normalKills":1,"normalTimestamp":1346240404000}]},

{
"name":"Tempel von Ahn'Qiraj","normal":2,"heroic":0,"id":3428,"bosses":[{"id":15727,"name":"C'Thun","normalKills":6,"normalTimestamp":1343395710000}]},

{
"name":"Karazhan","normal":2,"heroic":0,"id":3457,"bosses":
[{
"id":15690,"name":"Prinz Malchezaar","normalKills":1,"normalTimestamp":1331934461000}]},

{
"name":"Magtheridons Kammer","normal":2,"heroic":0,"id":3836,"bosses":[{"id":17257,"name":"Magtheridon","normalKills":1,"normalTimestamp":1337370759000}]},

{
"name":"Gruuls Unterschlupf","normal":2,"heroic":0,"id":3923,"bosses":
[{
"id":19044,"name":"Gruul der Drachenschlächter","normalKills":1,"normalTimestamp":1330910973000}]},

{
"name":"Höhle des Schlangenschreins","normal":2,"heroic":0,"id":3607,"bosses":
[{
"id":21212,"name":"Lady Vashj","normalKills":2,"normalTimestamp":1336572852000}]},

{
"name":"Festung der Stürme","normal":2,"heroic":0,"id":3845,"bosses":
[{
"id":19622,"name":"Kael'thas Sonnenwanderer","normalKills":2,"normalTimestamp":1338497955000}]},

{
"name":"Die Schlacht um den Hyjal","normal":2,"heroic":0,"id":3606,"bosses":[{"id":17968,"name":"Archimonde","normalKills":2,"normalTimestamp":1337368333000}]},

{
"name":"Der Schwarze Tempel","normal":2,"heroic":0,"id":3959,"bosses":
[{
"id":22917,"name":"Illidan Sturmgrimm","normalKills":4,"normalTimestamp":1341748030000}]},

{
"name":"Der Sonnenbrunnen","normal":2,"heroic":0,"id":4075,"bosses":[{"id":25315,"name":"Kil'jaeden","normalKills":1,"normalTimestamp":1335896831000}]},

{
"name":"Archavons Kammer","normal":2,"heroic":0,"id":4603,"bosses":
[{
"id":31125,"name":"Archavon der Steinwächter","normalKills":2,"normalTimestamp":1344775870000},{"id":33993,"name":"Emalon der Sturmwächter","normalKills":2,"normalTimestamp":1344775856000},{"id":35013,"name":"Koralon der Flammenwächter","normalKills":2,"normalTimestamp":1344775858000},{"id":38433,"name":"Toravon der Eiswächter","normalKills":2,"normalTimestamp":1344775994000}]},
{
"name":"Naxxramas","normal":2,"heroic":0,"id":3456,"bosses":[{"id":15956,"name":"Anub'Rekhan","normalKills":7,"normalTimestamp":1343323882000},
{
"id":15953,"name":"Großwitwe Faerlina","normalKills":7,"normalTimestamp":1343324154000},{"id":15952,"name":"Maexxna","normalKills":5,"normalTimestamp":1338917774000},
{
"id":15954,"name":"Noth der Seuchenfürst","normalKills":5,"normalTimestamp":1338918002000},
{
"id":15936,"name":"Heigan der Unreine","normalKills":5,"normalTimestamp":1338918207000},{"id":16011,"name":"Loatheb","normalKills":5,"normalTimestamp":1338919063000},
{
"id":16061,"name":"Instrukteur Razuvious","normalKills":5,"normalTimestamp":1338920524000},
{
"id":16060,"name":"Gothik der Ernter","normalKills":5,"normalTimestamp":1338921037000},
{
"id":0,"name":"Die vier Reiter","normalKills":5,"normalTimestamp":1338921543000},{"id":16028,"name":"Flickwerk","normalKills":5,"normalTimestamp":1338919308000},{"id":15931,"name":"Grobbulus","normalKills":5,"normalTimestamp":1338919473000},{"id":15932,"name":"Gluth","normalKills":5,"normalTimestamp":1338919602000},{"id":15928,"name":"Thaddius","normalKills":5,"normalTimestamp":1338920289000},{"id":15989,"name":"Saphiron","normalKills":5,"normalTimestamp":1338921768000},{"id":15990,"name":"Kel'Thuzad","normalKills":5,"normalTimestamp":1338922272000}]},

{
"name":"Das Obsidiansanktum","normal":2,"heroic":0,"id":4493,"bosses":[{"id":28860,"name":"Sartharion","normalKills":13,"normalTimestamp":1343403482000}]}, 
Das oben ist nur ein Auszug.. eig ist die Liste noch deutlich länger.. So weiter im geschehen.. wie wir sehen haben wir 3 mögliche konstulationen des Stringaufbaus:

1
Code:
"bosses":{"id":____,"name":"_____","normalKills":__,"normalTimestamp":____}]},
2
Code:
{"id":____,"name":"_____","normalKills":__,"normalTimestamp":____,"heroicKills":__,"heroicTimestamp":____},
3
Code:
{"id":____,"name":"_____","lfrKills":__,"lfrTimestamp":_____,"normalKills":__,"normalTimestamp":_____,"heroicKills":__,"heroicTimestamp":__}]},
so nun zur abfrage.. eig möchte ich gerne das alle abfragen da der string ja gleich bleibt sich halt nur segmente ergänze in einem string erscheint so das ich schöne groups habe.

hier mal der erste ansatz:
Code:
{"name":"(.*?)".?,"normal":.*?.?,"heroic":.*?.?,"id".*?.?,"bosses":\[{"id":.*?.?,"name":"(.*?)".?,"normalKills":(.*?),"normalTimestamp":.*?,"heroicKills":(.*?),"heroicTimestamp":.*?},
Nur die Abfrage bringt mal halt nur den direkten String.. wo auch heroicKills vorkommen.. anderes wird ja logisch ignoriert..

Ich denk fürs erste genug zum grübeln :)
02/23/2013 15:02 Shadow992#2
Eine einzige RegEx ist mit Sicherheit auch möglich hier, aber ich würde das anders angehen.

Zuerst einmal die einzelnen Klammern { und } in jeweils ein Array-Element speichern und anschließend bei "," splitten. Dann hat man alle "Variablennamen" mit Wert, also z.b.

"name":"Karazhan"
"normal":2

usw.

Wobei ich mit splitten natürlich kein einfaches Splitten per Delimiter meine, sondern ein "intelligentes" splitten. Hierfür kann man sicherlich auch RegEx benutzen, nur ich wüsste gerade nicht wie, deswegen würde ich dir empfehlen das ganze selbst umzusetzen mit einem Parser, der den Inhalt Zeichenweise abarbeitet.

Grober Pseudocode:
Code:
string temp=""
int momentaner_index=0
Solange wie Zeichen vorhanden:
{
   Wenn momentanes Zeichen==',' und momentanes Zeichen ist kein Inhalt von einem String:
   {
      info_array[momentaner_index]=temp
      temp=""
      momentaner_index+=1
   }
   ansonsten wenn momentanes zeichen nicht Inhalt von einem String ist:
   {
      wenn momentanes zeichen=='[':
          solange momentanes zeichen !=']':
            momentanes Zeichen an temp anhängen
        ansonsten:
          momentanes Zeichen an temp anhängen
   }
   nächstes Zeichen in dem String als momentanes Zeichen setzen
}

Wenn temp!="":
   info_array[momentaner_index]=temp
   temp=""
Konkreten Code kann ich dir erst geben, wenn ich weiß welche Sprache du verwendest, in AutoIt gäbes es z.b. noch ein paar Sachen, die man besser machen könnte. Aber das oben vorgestellte Prinzip sollte mit kleinen Ausbesserungen (habs ausm Kopf raus geschrieben) in jeder Sprache funktionieren.
02/23/2013 15:28 Schlüsselbein#3
Sieht mir aufn ersten Blick nach JSON aus.
Welche Sprache benutzt du? Such dir dafür n passenden JSON-Parser.
02/23/2013 15:33 Cnypher#4
Das mit json parser klingt nach ner Idee *g*

@Schlüsselbein
Das kommt aus einen VB.net Webrequest als Antwort im JSON Format. Die VB.net Anwendung dient dabei nur zum Crawlen.

Hab das mit dem } Werten im Array so schon in anderen Fällen gelöst. Nur ist dieser Auszug so lang das die Anzahl der Arrays relativ gigantisch werden.

Desweiteren muss ich halt schon nach den spezifisch langen String suchen da eben die Schlüßelbegriffe relativ häufig vorkommen.
02/23/2013 15:41 Schlüsselbein#5
Genau hier solltest du wirklich auf einen Parser zurückgreifen. Alles andere ist unnöiges, häßliches gefriemel.

Kurzes suchen sagt mir:
[Only registered and activated users can see links. Click Here To Register...]
Der funktioniert anscheinend auch wunderbar mit JSON.
Beispiel: [Only registered and activated users can see links. Click Here To Register...]

Sonst suchste dir halt ne andere für dich passende Library.
02/23/2013 15:55 Cnypher#6
[Only registered and activated users can see links. Click Here To Register...] hat die lösung erbracht - vielen dank für den Tipp