van explode en implode naar preg_replace()

Status
Niet open voor verdere reacties.

Niellles

Gebruiker
Lid geworden
21 jun 2008
Berichten
194
Beste,

Ik heb een stukje code waarmee ik een variabele om schrijf:

PHP:
$test = '4x10;2x11';
$mult = 2;
$array = explode(";",$test);

foreach($array as $value){
    $waardes = explode("x",$value);
    $array2[] = ($waardes[0]*$mult).'x'.$waardes[1];
}

$test2 = implode(";",$array2);

echo "$test * $mult wordt $test2";
//output: 4x10;2x11 * 2 wordt 8x10;4x11

Wat ik in feite wil is het getal voor de x vermenigvuldigen met een bepaalde factor...

Ik ben er van overtuigd dat dit ook met een reguliere expressie i.c.m. preg_replace moet kunnen, maar ik kom er niet uit... RegExs zijn sowieso niet mijn sterke kant... Iemand suggesties hoe dit te doen/relevante documentatie?

N.B. de variabele zou ook veel langer kunnen zijn, bijv: 10x8;15x90;100x89;10000x900, verder zit er (in principe) geen maximale lengte op de getallen.

Groeten,

Niels
 
Exact ja! Werkt top! Ik neem aan dat dit sneller werkt (ook al zal ik dat niet opmerken) dan m'n loops met implode.
Het ziet er nu als volgt uit:
PHP:
$test = '4x10;2x11;10x50;';
$mult = 4;
echo "$test<br />";

$line = preg_replace_callback(
        '|(\d+)x(\d+);|',
        function ($matches) {
            GLOBAL $mult;
            return ($matches[1]*$mult).'x'.$matches[2].';';
        },
        $test
);
echo $line;

Alleen zou ik $mult graag meegeven als argument voor die anonymous function, zo werkt ie als method namelijk niet:
PHP:
  public function changeAantalPersonen($aantalpersonen){
    $this->ingredient = preg_replace_callback('|(\d+)x(\d+);|',function($matches) {
            GLOBAL $aantalpersonen;
            return ($matches[1]*$aantalpersonen).'x'.$matches[2].';';},
            $this->ingredient);
            
            
  
  }

Ik heb zowel
PHP:
function($matches,$aantalpersonen)
als
PHP:
function($matches,$aantalpersonen) use ($matches,$aantalpersonen)
werken helaas niet. Hoe kan ik dat nou eens voor elkaar krijgen?

Groet,

Niels
 
Laatst bewerkt:
Als je de $mult in dezelfde class zet waar ook de regexp-method in zit dan kun je er bij met $this->mult

PHP:
<?php


class foo
{
	private  $mult;
	
	public function __construct($pIntMult)
	{
		$this->mult=$pIntMult;
	}

	public function calc($test)
	{
		$line = preg_replace_callback(
				'|(\d+)x(\d+);|',
				function ($matches) {
					
					return ($matches[1]*self::$this->mult).'x'.$matches[2].';';
				},
				$test
		);
		return $line;
	}
	
	
}


$objFoo = new foo(4);
echo $objFoo->calc('4x10;2x11;10x50;');

$objFoo = new foo(2);
echo $objFoo->calc('4x10;2x11;10x50;');
 
Zoiets had ik ook al bedacht alleen is changeAantalPersonen() een method van een class recept, die al een andere constructor heeft.
In een ideale situatie zou ik hem ongeveer zo willen aanroepen:
PHP:
$recept = New recept(array('action' => 'get', 'id' => 1));
$recept->changeAantalPersonen(5);

Die constructor van recept is een array omdat ik op verschillende manieren wil laden, die variabele in changeAantalPersonen($aantalpersonen) heb ik dus echt nodig. Maar hoe?
 
Zoiets had ik ook al bedacht alleen is changeAantalPersonen() een method van een class recept, die al een andere constructor heeft.

Dat is geen probleem, de method hoeft geen onderdeel van de receptclass te zijn, de receptclass moet alleen weten hoe hij de berekening doet en daarvoor kan de receptclass ook een andere class aanroepen die feitelijk niets anders doet dan de $mult onthouden in zijn eigen private property:

PHP:
<?php
class recept
{
	public function doStuff($string, $mult)
	{
		$objCalculator = new foo();
		return $objCalculator->multiply($string, $mult);
	}
}


class foo
{
	private $intMultiplier;
	
	public function multiply($test, $mult)
	{
		$this->intMultiplier  = $mult;
		$line = preg_replace_callback(
				'|(\d+)x(\d+);|',
				function ($matches) {
					
					return ($matches[1]*$this->intMultiplier).'x'.$matches[2].';';
				},
				$test
		);
		return $line;
	}
}

$objRecept = new recept();
echo $objRecept->doStuff('4x10;2x11;10x50;', 3);

Dan heb je praktisch een strategy pattern; je kunt de calculator nu ook vervangen door instanties van andere classen die complexere berekeningen kunnen doen, b.v. op basis van engelse maten ipv simpelweg vermenigvuldigen, zonder de receptclass wezenlijk te hoeven aanpassen.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan