views:

113

answers:

3

What I need to be able do is format data in a variable, like so:

format: xxx-xxx variable: 123456 output: 123-456

The problem is I need to be able to change the format, so a static solution wouldn't work. I also like to be able to change the variable size, like:

format: xxx-xxx variable: 1234 output: 1-234

All ideas are welcome! Thanks for your help!

Note: All of the variables will be numbers

Edit I should have been clear on the format its not going to always be grouping of 3, and it may have more then "-" as a symbol, the groups will be inconstant 1-22-333-4444 it will only be in grouping of 1-5

+1  A: 

Your best bet is preg_replace.

Regular expressions take some getting used to, but this is probably your best bet...

EDIT:

//initial parsing
$val = preg_replace(
    '/(\d*?)(\d{1,2}?)(\d{1,3}?)(\d{1,4})$/', 
    '${1}-${2}-$[3}-${4}', 
    $inputString
);

//nuke leading dashes
$val - preg_replace('^\-+', '', $val);

The key is to make every set, except the righ-most one non-greedy, allowing for a right-side oriented pattern match.

Tracker1
Is there a way to set a patten without knowing the positions?
Scott
@scott, not sure what you mean? You can do a pattern match without the end string marker `$/` ... i would suggest some reading on the use of regular expressions...
Tracker1
read your updates... you could wrap his into a function where the pattern, format, and input string are passed in, and the results returned...
Tracker1
A: 

You could implement the strategy pattern and and have new formatting classes that are swappable at run time. It looks complicated if you haven't seen it before but it really helps with maintainability and allows you to switch the formatter with the setFormatter() at any time.

class StyleOne_Formatter implements Formatter
{
    public function format($text)
    {
      return substr($text,0,3).'-'.substr($text,3);
    }
}

class StyleTwo_Formatter implements Formatter
{
    public function format($text)
    {
      return substr($text,0,1).'-'.substr($text,1);
    }
}

Then you would have your formatting class which would be like so:

class NumberFormatter implements Formatter
{

   protected $_formatter = null;

   public function setFormatter(Formatter $formatter)
   {
      $this->_formatter = $formatter;
   }

   public function format($text)
   {
     return $this->_formatter->format($text);
   }
}

Then you could use it like this:

 $text = "12345678910";
 $formatter = new NumberFormatter();

 $formatter->setFormatter(new StyleOne_Formatter());
 print $formatter->format($text);
 // Outputs 123-45678910

 $formatter->setFormatter(new StyleTwo_Formatter());
 print $formatter->format($text);
 // Outputs 1-2345678910
xenon
I tried this type of thing before but it needs more then one group per block, I am using php5.
Scott
Don't think I understand what you mean by one group per block
xenon
The formatters can return results from a preg_replace like Tracker1's solution but u can have multiple formatters for different things.
xenon
Your script outputs like 123-45678910but I need to be able to output more groups like 12-345-67-8910
Scott
Then you can modify the algorithm form producing it, i was demonstrating a way you could easily change the algorithm. It's up to you to decide what your algorithm does. For that format you would need substr($input,0,2).'-'.substr($input,2,3).'-'.substr($input,5,2).'-'.substr($input,7); but there are better ways to generate this output (preg_replace)
xenon
I see what you mean I am looking into preg_replace, trying to work it out, thanks for your help.
Scott
No worries mate =)
xenon
A: 

If the input you are formatting is always an integer you can try number_format and format as money (thousands etc..) Here is a solution which takes any string and turns it into your desired format:

$split_position = 3;
$my_string      = '';
echo strrev(implode('-',(str_split(strrev($my_string),$split_position))));

input: 1234;     output: 1-234
input: abcdefab; output: ab-cde-fab
input: 1234567   output: 1-234-567
duckyflip
This would work great if it could have more then one group size.
Scott