Skip to content

Commit 95a330c

Browse files
committed
replace preg_replace_callback with for loops; add support for an asterisk in bothify
1 parent 4d1acaf commit 95a330c

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

src/Faker/Provider/Base.php

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,19 @@ public static function shuffleString($string = '', $encoding = 'UTF-8')
317317
return join('', static::shuffleArray($array));
318318
}
319319

320+
private static function replaceWildcard($string, $wildcard = '#', $callback = 'static::randomDigit')
321+
{
322+
if (($pos = strpos($string, $wildcard)) === false) {
323+
return $string;
324+
}
325+
for ($i = $pos, $last = strrpos($string, $wildcard, $pos) + 1; $i < $last; $i++) {
326+
if ($string[$i] === $wildcard) {
327+
$string[$i] = call_user_func($callback);
328+
}
329+
}
330+
return $string;
331+
}
332+
320333
/**
321334
* Replaces all hash sign ('#') occurrences with a random number
322335
* Replaces all percentage sign ('%') occurrences with a not null number
@@ -329,9 +342,11 @@ public static function numerify($string = '###')
329342
// instead of using randomDigit() several times, which is slow,
330343
// count the number of hashes and generate once a large number
331344
$toReplace = array();
332-
for ($i = 0, $count = strlen($string); $i < $count; $i++) {
333-
if ($string[$i] === '#') {
334-
$toReplace []= $i;
345+
if (($pos = strpos($string, '#')) !== false) {
346+
for ($i = $pos, $last = strrpos($string, '#', $pos) + 1; $i < $last; $i++) {
347+
if ($string[$i] === '#') {
348+
$toReplace[] = $i;
349+
}
335350
}
336351
}
337352
if ($nbReplacements = count($toReplace)) {
@@ -347,7 +362,7 @@ public static function numerify($string = '###')
347362
$string[$toReplace[$i]] = $numbers[$i];
348363
}
349364
}
350-
$string = preg_replace_callback('/\%/u', 'static::randomDigitNotNull', $string);
365+
$string = self::replaceWildcard($string, '%', 'static::randomDigitNotNull');
351366

352367
return $string;
353368
}
@@ -360,17 +375,21 @@ public static function numerify($string = '###')
360375
*/
361376
public static function lexify($string = '????')
362377
{
363-
return preg_replace_callback('/\?/u', 'static::randomLetter', $string);
378+
return self::replaceWildcard($string, '?', 'static::randomLetter');
364379
}
365380

366381
/**
367-
* Replaces hash signs and question marks with random numbers and letters
382+
* Replaces hash signs ('#') and question marks ('?') with random numbers and letters
383+
* An asterisk ('*') is replaced with either a random number or a random letter
368384
*
369385
* @param string $string String that needs to bet parsed
370386
* @return string
371387
*/
372388
public static function bothify($string = '## ??')
373389
{
390+
$string = self::replaceWildcard($string, '*', function () {
391+
return mt_rand(0, 1) ? '#' : '?';
392+
});
374393
return static::lexify(static::numerify($string));
375394
}
376395

test/Faker/Provider/BaseTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,11 @@ public function testBothifyCombinesNumerifyAndLexify()
276276
$this->assertRegExp('/foo[a-z]Ba\dr/', BaseProvider::bothify('foo?Ba#r'));
277277
}
278278

279+
public function testBothifyAsterisk()
280+
{
281+
$this->assertRegExp('/foo([a-z]|\d)Ba([a-z]|\d)r/', BaseProvider::bothify('foo*Ba*r'));
282+
}
283+
279284
public function testAsciifyReturnsSameStringWhenItContainsNoStarSign()
280285
{
281286
$this->assertEquals('fooBar?', BaseProvider::asciify('fooBar?'));

0 commit comments

Comments
 (0)