Javascript mintaillesztés, Node.js
Sziasztok,
egy elég misztikus hibába ütköztem, és nem nagyon tudok a végére járni.
Van egy node.js scriptem, UDP-n érkező adatokat dolgoz fel. A bejövő streamet természetsen stringgé alakítom és kivágom belőle azt, ami nekem kell.
Szóval van ez a kódrészlet:A konzolba az alábbiakat írja:
(sorkihagyások nincsenek, csak gondoltam tagolom a jobb olvashatóság miatt)
A "this.patterns.logsync" egy RegExp objektum.
A probléma az, hogy a harmadik console.log üzenet null-t ad vissza. Aminek persze nem nullnak kellene lennie.
A fenti adatokkal csináltam manuálisan egy js fájlt, és kipróbáltam, úgy mit ad.Az eredmény természetesen az elvárt, azaz a harmdik sorban nem null van, hanem egy tömb dumpja.
Kipróbáltam ugyanezt a http://www.regextester.com/-on is, beírva a megfelelő paramétereket, beállítva flageket (g és i), és úgy is helyes eredményt ad.
A dologhoz hozzá tartozik, hogy jön egyszerre mondjuk 7 sor adat, amiből 4 dolgozódik fel (4-re nem null a res változó értéke a regexp.exec után, hanem az elvárt). Az UDP fogadó nyilván async módon hívogatja meg az illesztést is tartalmazó függvényt, ahogy kap egy sort.
■ egy elég misztikus hibába ütköztem, és nem nagyon tudok a végére járni.
Van egy node.js scriptem, UDP-n érkező adatokat dolgoz fel. A bejövő streamet természetsen stringgé alakítom és kivágom belőle azt, ami nekem kell.
Szóval van ez a kódrészlet:
res = this.patterns.logsync.exec(logLine);
console.log(logLine);
console.log(this.patterns.logsync);
console.log(res);
log L 02/13/2013 - 13:13:40: "rezso :D<13478><STEAM_0:0:123456789><CT>" logsync (ip "188.188.188.128:27005") (port "0") (hit "0") (hit_head "0") (hit_wall "3") (kill "21") (kill_head "8") (kill_wall "0") (shot "0") (death "7") (time "718")
/log L ([0-9]{2})/([0-9]{2})/([0-9]{4}) - ([0-9]{2}):([0-9]{2}):([0-9]{2}): "(.*?)<([0-9]+)><((STEAM|VALVE|BOT)(.*?))><([A-Z_]*)>" logsync .ip "(.*?)". .port "([0-9-]*)". .hit "([0-9-]*)". .hit_head "([0-9-]*)". .hit_wall "([0-9-]*)". .kill "([0-9-]*)". .kill_head "([0-9-]*)". .kill_wall "([0-9-]*)". .shot "([0-9-]*)". .death "([0-9-]*)". .time "([0-9-]*)"./gi
null
/log L ([0-9]{2})/([0-9]{2})/([0-9]{4}) - ([0-9]{2}):([0-9]{2}):([0-9]{2}): "(.*?)<([0-9]+)><((STEAM|VALVE|BOT)(.*?))><([A-Z_]*)>" logsync .ip "(.*?)". .port "([0-9-]*)". .hit "([0-9-]*)". .hit_head "([0-9-]*)". .hit_wall "([0-9-]*)". .kill "([0-9-]*)". .kill_head "([0-9-]*)". .kill_wall "([0-9-]*)". .shot "([0-9-]*)". .death "([0-9-]*)". .time "([0-9-]*)"./gi
null
(sorkihagyások nincsenek, csak gondoltam tagolom a jobb olvashatóság miatt)
A "this.patterns.logsync" egy RegExp objektum.
A probléma az, hogy a harmadik console.log üzenet null-t ad vissza. Aminek persze nem nullnak kellene lennie.
A fenti adatokkal csináltam manuálisan egy js fájlt, és kipróbáltam, úgy mit ad.
#!/usr/bin/node
logLine = 'log L 02/13/2013 - 13:13:40: "rezso :D<13478><STEAM_0:0:123456789><CT>" logsync (ip "188.188.188.128:27005") (port "0") (hit "0") (hit_head "0") (hit_wall "3") (kill "21") (kill_head "8") (kill_wall "0") (shot "0") (death "7") (time "718")';
logsyncPattern = new RegExp('log L ([0-9]{2})/([0-9]{2})/([0-9]{4}) - ([0-9]{2}):([0-9]{2}):([0-9]{2}): "(.*?)<([0-9]+)><((STEAM|VALVE|BOT)(.*?))><([A-Z_]*)>" logsync .ip "(.*?)". .port "([0-9-]*)". .hit "([0-9-]*)". .hit_head "([0-9-]*)". .hit_wall "([0-9-]*)". .kill "([0-9-]*)". .kill_head "([0-9-]*)". .kill_wall "([0-9-]*)". .shot "([0-9-]*)". .death "([0-9-]*)". .time "([0-9-]*)".', 'gi');
res = logsyncPattern.exec(logLine);
console.log(logLine);
console.log(logsyncPattern);
console.log(res);
Kipróbáltam ugyanezt a http://www.regextester.com/-on is, beírva a megfelelő paramétereket, beállítva flageket (g és i), és úgy is helyes eredményt ad.
A dologhoz hozzá tartozik, hogy jön egyszerre mondjuk 7 sor adat, amiből 4 dolgozódik fel (4-re nem null a res változó értéke a regexp.exec után, hanem az elvárt). Az UDP fogadó nyilván async módon hívogatja meg az illesztést is tartalmazó függvényt, ahogy kap egy sort.
Biztos?
logLine
-t? Nem lehet, hogy az még mindig StringBuffer, és azóta íródott bele adat?Kódrészlettel válaszolnék,
Oké, fél siker: Ha már itt
Ha már itt tartunk, megnéztem úgy is a szcenáriót, hogy a regexp objektumot minden alkalommal létrehozom (new). Ekkor sikerült feldolgoznia minden beérkező kérést. Azt viszont nem értem, hogy egy számomra readonly objektum miért veszíti érvényét amikor több szálon használom fel.
A szálak függetlenek
Van egy objektum (stat),
Amit sejtesz, az szerintem nem magyarázza, hogy miért hagy ki egy-egy sort feldolgozásnál (ahogy írtam, 7-ből 4-nél nincs gond).
Ellenben ha a RegExp-eket akkor hozom létre, amikor a stat objektum metódusa megkapja az aktuális log sort, akkor minden rendben működik.
Cache
new RegExp
esetén). Ez természetesen implementáció függő.Most a regex-el van gond,
Van egy olyan kellemetlen
RegExp
objektumoknak, hogy van állapotuk. Azexec
módosítja ezt az állapotot, majd ag
flag miatt az exec ezt figyelembe is veszi (pontosan nem ismerem a mechanizmust, de gondolom alastIndex
tulajdonság miatt nem sikerül az illesztés)Íme egy minimálpélda:
Mindig létrehozni egy új
RegExp
objektumot, vagy az illesztés előtt alastIndex
tulajdonságot ki kell nullázni.Ha ugyanazt a string-et adod
String.match-et kell használni RegExp.exec helyett, vagy tisztában kell lenni azzal, hogy melyik függvény mit csinál...
Ha ugyanazt a string-et adod
Nem kell ugyanannak a stringnek lennie:
Hmm, hát akkor resetelni kell