0

I have numbers that I would like to replace with letters:

<?php
$text = 'I have 10 apples';
$numbers = array(0, 1, 2,..., 10);
$letters = array('zero', 'one', 'two',... 'ten');
echo str_replace($numbers, $letters, $text); 
// output is 'I have onezero apples' instead of 'I have ten apples'
?>

How could it be done to generate correct output? It should also work not only for numbers but also for words (inside $number array may be also letters/words)

Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291
Abu Rayane
  • 241
  • 1
  • 14

3 Answers3

1
$text = 'I have 10 apples';
$numbers = array(10, 0, 1, 2);
$letters = array('ten','zero', 'one', 'two');
echo str_replace($numbers, $letters, $text);

but this would not be long term solution if you added more values you would need to use if statements or similar to compare before doing the replacement

  • If you only require positive number the below answer is better using array reverse, if you need to include negative numbers it will require more conditional checking – Andrew Crawford Jul 30 '14 at 11:24
1

You should simply sort array descending with key length and it will both for numbers and other strings. The following code should work for you:

<?php
$text = 'I have 10 (or 21) apples and I would like to bake an apple pie';
$numbers = array(0, 1, 2, 10, 21, ' a ', ' an ');
$letters = array('zero', 'one', 'two','ten','twenty one',' A ',' AN ');

$data = array_combine($numbers, $letters);

krsort($data, SORT_STRING);

echo str_replace(array_keys($data), array_values($data), $text);

// Output: I have ten (or twenty one) apples and I would like to bake AN apple pie
?>

EDIT

For the following input data:

$text = 'An 1 Anha 2 Anh 21';
$numbers = array(0, 1, 2, 10, 21, ' a ', ' an ', 'An','Anh', 'Anha');
$letters = array('zero', 'one', 'two','ten','twenty one',' A ',' AN ', 'Hi', 'Hello', 'Bye');

$data = array_combine($numbers, $letters);

krsort($data, SORT_STRING);

echo str_replace(array_keys($data), array_values($data), $text);

using the same method will give you:

Hi one Bye two Hello twenty one

output as intended

How does it work - explanation

With array_combine() function you create one new array, that have keys from $numbers array and values from $letters. This function is used only because input data in 2 separate arrays. If there were used associative array at the beginning: $data[0] => 'zero'; ... $data[1] => 'one';, .... this function would be unnecessary.

Now because some keys may contain other keys, you need to sort your data that way that you have the longest keys before shorter ones. It makes that 10 will be changed into ten and not one zero. You can use for that krsort() function that sorts array using keys for compare (using array_combine our keys are now data from $numbers array) in reverse order using SORT_STRING comparison so if we have words c, a, ccc and cc it will sort it in reverse other (normal other is a, c, cc, ccc) so they will be ccc, cc, c, a.

At last after sorting, we need to pass data to str_replace. This function needs keys and values and we don't have them separate because earlier we created one array using array_combine() and sort it. But we can now get keys and values from that array using array_keys() and array_values() functions.

Marcin Nabiałek
  • 109,655
  • 42
  • 258
  • 291
  • how about replacing words with images, if I have an array of words that are mostly similar, I am looking for replacing a specific word, i.e: "An" will be replaced with "Hi", and "Anh" with "Hello" and "Anha" with "Bye" – Abu Rayane Jul 30 '14 at 12:45
  • @AbuRayane Have you checked this code? It should work. For `An 1 Anha 2 Anh 21` it will give you output: `Hi one Bye two Hello twenty one` – Marcin Nabiałek Jul 30 '14 at 12:53
  • is this the code `$text = 'An 1 Anha 2 Anh 21'; $numbers = array(0, 1, 2, 10, 21, ' a ', ' an ', 'An','Anh', 'Anha'); $letters = array('zero', 'one', 'two','ten','twenty one',' A ',' AN ', 'Hi', 'Hello', 'Bye'); echo str_replace($numbers, $letters, $text);` – Abu Rayane Jul 30 '14 at 14:36
  • @AbuRayane Yes, I edited my answer and added second example. I don't see any case it doesn't work. Do you? Have you tested it at all? – Marcin Nabiałek Jul 30 '14 at 14:43
  • @AbuRayane Have you tested the whole code? Look at my answer. I don't use `$numbers` and `$letters` in my str_replace. Again - look carefully at my answer. I've added full code to **EDIT** in case you misunderstood it. – Marcin Nabiałek Jul 30 '14 at 17:56
  • could you please explain array_combine and ksort – Abu Rayane Jul 31 '14 at 11:03
  • @AbuRayane I've added explanation to my answer – Marcin Nabiałek Jul 31 '14 at 11:13
0

The problem is that it first replaces 1 by one then 0 by zero.

As suggested you can reverse the order so it will first look for higher numbers, but as also said this is a long road perhaps.

Check this question instead: Is there an easy way to convert a number to a word in PHP?

Or, try a preg_match.

Or let PHP reverse the arrays:

$numbers = array_reverse(array(0, 1, 2,..., 10));
$letters = array_reverse(array('zero', 'one', 'two',... 'ten'));
Community
  • 1
  • 1
Daniel W.
  • 31,164
  • 13
  • 93
  • 151
  • The issue is not only with numbers, it might be even with words to be replace, i.e: I have two words here "Anh" and "Anha", and I would replace "Anh" with "Hello" and "Anha" with "Hi". I think using preg_replace with specific rules will be better – Abu Rayane Jul 30 '14 at 11:58