Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C, PHP: Regex-ongelma

punppis [09.05.2014 11:47:57]

#

Tässä on työn alla C++:lla koodatun projektin porttaaminen C#:lle. Kyseessä on cocos2d-x pelimoottori ja yritän tehdä PHP-skriptiä, jolla koodin voi helposti muuttaa C++:sta C#:ksi.

Netistä löytyy kyllä ohjelmia syntaksin muuttamiseen, mutta nämä cocos2d-x:ään liittyvät jutut pitää tehdä käsin.

// spriten luominen c++:lla
CCSprite* spr = CCSprite::create("foo.png");
// spriten luominen c#:lla
CCSprite spr = new CCSprite("foo.png");

C++:n staattiset funktiot on siis korvattu C#:ssa erilaisilla konstruktoreilla.

Ongelma: luomani regex ei toimi kaikissa tapauksissa, esim. tästä koodista regex osaa muuttaa vain ensimmäisen rivin.

Lähde:

// käyttämäni c++ -> c# konversio-ohjelma palauttaa tämän
CCSprite spr = CCSprite.createWithTest("test.png");
CCSprite spr = CCSprite.create("test.png");

public partial class MainMenu
{
	public bool init()
	{
                CCSprite spr = CCSprite.create("test.png");
                CCSprite spr = CCSprite.createWithTest("test.png");
	}
}

Tulos:

CCSprite spr = new CCSprite("test.png"); // Ok
CCSprite spr = CCSprite.create("test.png"); // ei toimi

public partial class MainMenu
{
	public bool init()
	{
                CCSprite spr = CCSprite.create("test.png"); // ei toimi
                CCSprite spr = CCSprite.createWithTest("test.png"); // ei toimi
	}
}

Regex:

preg_replace('/([a-zA-Z]+)\.create[a-zA-Z]*\((.*)\)/', "new $1($2)", $source);

Antti Laaksonen [09.05.2014 12:01:09]

#

Outoa, koska minulla antamasi säännöllinen lauseke muuttaa molemmat rivit oikein.

Yksi mahdollinen ongelma on siinä, että (.*) ottaa mukaan mahdollisimman paljon merkkejä eikä lopeta ensimmäiseen loppusulkuun. Korjaus tähän on muuttaa kyseinen kohta muotoon (.*?). Tämän ei pitäisi kuitenkaan vaikuttaa tapaukseesi, koska . ei täsmää rivinvaihtoon.

punppis [09.05.2014 12:39:09]

#

Kysymysmerkin laittaminen korjasi ongelman... Osaatko Antti selittää miksi näin tapahtuu? Eikö .*? tarkoita "mikä tahansa merkki 0+ kertaa, 0 tai 1 kertaa".

vesikuusi [09.05.2014 12:57:34]

#

PHP-oppaasta...

https://www.ohjelmointiputka.net/oppaat/opas.php?tunnus=php_16:

Kysymysmerkki määrittää, että lausekkeen osa tunnistaa mahdollisimman lyhyen pätkän tekstiä. Ilman kysymysmerkkiä tunnistettava osa olisi mahdollisimman pitkä --

Lisäys: Eli tuossa (.*?)-tapauksessa näin. Mutta esim. bracket expressionin perässä täsmää juurikin 0-1 kertaa.

Metabolix [09.05.2014 15:48:03]

#

Kysymysmerkki toisto-operaattorin perässä tarkoittaa, että toisto-operaattori ei ole ahne (greedy) vaan laiska (lazy) eli ottaa mahdollisimman vähän toistoja.

Nykyinenkin (tai korjattu) lausekkeesi toimii periaatteessa väärin sulkujen kanssa: vaikkapa tekstistä ”A.create(f(1),2)” tunnistetaan puutteellinen pätkä ”A.create(f(1)” eli sulut eivät mene tasan ja toinen parametri puuttuu. Jos vaikka korvauksessa olisi uudet sulut koko koodin ympärillä, tuloksena olisi ”new (A(f(1)),2)” eli selvästi viallinen koodi.

Koska et lausekkeessa muuta sulkuja tai niiden sisältöä, voit jättää lausekkeesta kokonaan pois kohdan ”(.*)\)” ja vastaavasti korvauksesta kohdan ”$2)”.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta