Formating a specific input number to another format - php

I need to format the following number 0825632332 to this format +27 (0)82 563 2332.
Which combination of functions would work the best, should I use regular expressions or normal string functions to perform the re-formatting? And how?

I think using a regexp is the best way, maybe something like this :
$text = preg_replace('/([0-9])([0-9]{2})([0-9]{3})([0-9]{4})/', '+27 ($1) $2 $3 $4', $num);
Be aware that $num must be a string since your number starts with 0.
You can also use character class :
$text = preg_replace('/(\d)(\d{2})(\d{3})(\d{4})/', '+27 ($1) $2 $3 $4', $num);

Since you asked - non regex solution:
<?php
function phnum($s, $format = '+27 (.).. ... ....') {
$si = 0;
for ($i = 0; $i < strlen($format); $i++)
if ($format[$i] == '.')
$output[] = $s[$si++];
else
$output[] = $format[$i];
return join('',$output);
}
echo phnum('0825632332');
?>

Regex will work nicely, replace
(\d)(\d{2})(\d{3})(\d{4})
by
+27 (\1)\2 \3 \4
You can also perform string submatching if you want.

Related

PHP Replace Leading Zeros with Same Number of Spaces

I'd like to replace a string like 0001 with " 1" with 3 spaces.
I've tried str_replace but that doesn't work on 0010.
I've tried some preg_replace but can't get the replacement right to replace the same number
I've written this basic thing and it works, but am looking for something more efficient if possible.
$pin = '0010';
$temp = ltrim($pin, '0');
$spaces = strlen($pin) - strlen($temp);
for ($x=1;$x<=$spaces;$x++) $temp = ' '.$temp;
echo $temp;
Closest I got with preg_replace was this but I'm not sure what to do with replacement:
preg_replace('/0+/', ' ', $pin)
\G for the win!
https://www.regular-expressions.info/continue.html
\G will match the start of the string and continue to match until it can't.
What is the use of '\G' anchor in regex?
Match a zero from the start of the string, then match every following zero one-at-a-time. Replace every matched zero with a space.
Code: (Demo)
$pin = '0010';
var_export(preg_replace('~\G0~', ' ', $pin));
Output:
' 10'
I don't see how to do this any easier with a regular expression, but you could make your other code more concise by using str_repeat:
$pin = '0010';
$temp = ltrim($pin, '0');
$spaces = strlen($pin) - strlen($temp);
$new_pin = str_repeat(' ', $spaces) . $temp;
echo $new_pin;
You said:
but am looking for something more efficient if possible
First, note that a one-liner isn't necessarily efficient(as you tried for preg_replace() and regex is actually a bit slower since it gets compiled first).
Second, you can better adopt for just a 2 pass approach over the string. This also edits the string in-place without extra string variables which is desirable in your case.
Snippet:
<?php
$str = '000010';
$len = strlen($str);
for($i = 0; $i < $len; ++$i){
if($str[$i] == '0'){
$str[$i] = ' ';
}else{
break;
}
}
echo $str;

Formatting string according to pattern without regex in php

How can I format an arbitrary string according to a flexible pattern? The only solution I came up with is using regular expressions, but then I need 2 "patterns" (one for the search and one for the output).
Example:
$str = '123ABC5678";
Desired output: 12.3AB-C5-67.8
I would like to use a pattern in a variable (one that a user can easily define without knowledge of regular expressions) It could look like this:
$pattern = '%%.%%%-%%-%%.%';
So the user would just have to use 2 different characters (% and .)
A solution with regex would look like this:
$str = '123ABC5678';
$pattern_src = '#(.{2})(.{3})(.{2})(.{2})(.{1})#';
$pattern_rpl = "$1.$2-$3-$4.$5";
$res = preg_replace($pattern_src, $pattern_rpl, $str);
//$res eq 12.3AB-C5-67.8
Way too complicated since the user would need to define $pattern_src and $pattern_rpl. If the string could vary in length, it would be even more complex to explain.
Yes, I could write a function/parser that builds the required regular expressions based on a simple user pattern like %%.%%%-%%-%%.%. But I wonder if there is any "built in" way to achieve this with php? I was thinking about sprintf etc., but that doesn't seem to do the trick. Any ideas?
I was thinking about sprintf etc., but that doesn't seem to do the trick.
You're on the right track. You can accomplish this with vsprintf as follows:
$str = '123ABC5678';
$pattern = '%%.%%%-%%-%%.%';
echo vsprintf(str_replace('%', '%s', $pattern), str_split($str));
Output:
12.3AB-C5-67.8
This is assuming the number of % characters in $pattern match the length of $str.
Why not write a simple parser that works as follows:
For each character of pattern:
if you match percent character, output next character from input
if you match any other character, output it
$str = '123ABC5678';
$pattern = '%%.%%%-%%-%%.%';
if (strlen($str) < substr_count($pattern, '%'))
Die('The length of input string is lower than number number of placeholders');
$len = strlen($pattern);
$stringIndex = 0;
$output = '';
for ($i = 0; $i < $len; $i++) {
if ($pattern[$i] === '%') {
$output .= $str[$stringIndex];
$stringIndex++;
} else {
$output .= $pattern[$i];
}
}
echo $output;
I have a similar solution that looks like this.
<?php
$format = '%%.%%%-%%-%%.%';
$string = '123ABC5678';
$new_string = '';
$c = 0;
for( $i = 0; $i < strlen( $format ); $i++ )
{
if( $format[ $i ] == '%' )
{
$new_string .= $string[ $c ];
$c++;
}
else
{
$new_string .= $format[ $i ];
}
}
echo $new_string;
Output:
12.3AB-C5-67.8
How about this pattern from the user?
2.3-2-2.1
Where the pattern is a number means n chars, a dot or dash means add a dot or dash.
Now you make a regex to parse the user input:
preg_match_all("/(.)/", $User_input, $pattern);
Now you will have an array with either numbers or dots and dashes.
So loop through the array and build the string:
$string = '123ABC5678';
$User_input = "2.3-2-2.1";
preg_match_all("/(.)/", $User_input, $pattern);
$i=0;
$str="";
foreach($pattern[1] as $val){
if(is_numeric($val)){
$str .= substr($string,$i,$val);
$i=$i+$val;
}else{
$str .= $val;
}
}
echo $str;
https://3v4l.org/5eg5G

str replace - replace the x-value

Assuming I have a string
$str="0000,1023,1024,1025,1024,1023,1027,1025,1024,1025,0000";
there are three 1024, I want to replace the third with JJJJ, like this :
output :
0000,1023,1024,1025,1024,1023,1027,1025,JJJJ,1025,0000
how to make str_replace can do it
thanks for the help
As your question asks, you want to use str_replace to do this. It's probably not the best option, but here's what you do using that function. Assuming you have no other instances of "JJJJ" throughout the string, you could do this:
$str = "0000,1023,1024,1025,1024,1023,1027,1025,1024,1025,0000";
$str = str_replace('1024','JJJJ',$str,3)
$str = str_replace('JJJJ','1024',$str,2);
Here is what I would do and it should work regardless of values in $str:
function replace_str($str,$search,$replace,$num) {
$pieces = explode(',',$str);
$counter = 0;
foreach($pieces as $key=>$val) {
if($val == $search) {
$counter++;
if($counter == $num) {
$pieces[$key] = $replace;
}
}
}
return implode(',',$pieces);
}
$str="0000,1023,1024,1025,1024,1023,1027,1025,1024,1025,0000";
echo replace_str($str, '1024', 'JJJJ', 3);
I think this is what you are asking in your comment:
function replace_element($str,$search,$replace,$num) {
$num = $num - 1;
$pieces = explode(',',$str);
if($pieces[$num] == $search) {
$pieces[$num] = $replace;
}
return implode(',',$pieces);
}
$str="0000,1023,1024,1025,1024,1023,1027,1025,1024,1025,0000";
echo replace_element($str,'1024','JJJJ',9);
strpos has an offset, detailed here: http://php.net/manual/en/function.strrpos.php
So you want to do the following:
1) strpos with 1024, keep the offset
2) strpos with 1024 starting at offset+1, keep newoffset
3) strpos with 1024 starting at newoffset+1, keep thirdoffset
4) finally, we can use substr to do the replacement - get the string leading up to the third instance of 1024, concatenate it to what you want to replace it with, then get the substr of the rest of the string afterwards and concatenate it to that. http://www.php.net/manual/en/function.substr.php
You can either use strpos() three times to get the position of the third 1024 in your string and then replace it, or you could write a regex to use with preg_replace() that matches the third 1024.
if you want to find the last occurence of your string you can used strrpos
Do it like this:
$newstring = substr_replace($str,'JJJJ', strrpos($str, '1024'), strlen('1024') );
See working demo
Here's a solution with less calls to one and the same function and without having to explode, iterate over the array and implode again.
// replace the first three occurrences
$replaced = str_replace('1024', 'JJJJ', $str, 3);
// now replace the firs two, which you wanted to keep
$final = str_replace('JJJJ', '1024', $replaced, 2);

Increment integer at end of string

I have a string, "Chicago-Illinos1" and I want to add one to the end of it, so it would be "Chicago-Illinos2".
Note: it could also be Chicago-Illinos10 and I want it to go to Chicago-Illinos11 so I can't do substr.
Any suggested solutions?
Complex solutions for a really simple problem...
$str = 'Chicago-Illinos1';
echo $str++; //Chicago-Illinos2
If the string ends with a number, it will increment the number (eg: 'abc123'++ = 'abc124').
If the string ends with a letter, the letter will be incremeted (eg: '123abc'++ = '123abd')
Try this
preg_match("/(.*?)(\d+)$/","Chicago-Illinos1",$matches);
$newstring = $matches[1].($matches[2]+1);
(can't try it now but it should work)
$string = 'Chicago-Illinois1';
preg_match('/^([^\d]+)([\d]*?)$/', $string, $match);
$string = $match[1];
$number = $match[2] + 1;
$string .= $number;
Tested, works.
explode could do the job aswell
<?php
$str="Chicago-Illinos1"; //our original string
$temp=explode("Chicago-Illinos",$str); //making an array of it
$str="Chicago-Illinos".($temp[1]+1); //the text and the number+1
?>
I would use a regular expression to get the number at the end of a string (for Java it would be [0-9]+$), increase it (int number = Integer.parse(yourNumberAsString) + 1), and concatenate with Chicago-Illinos (the rest not matched by the regular expression used for finding the number).
You can use preg_match to accomplish this:
$name = 'Chicago-Illinos10';
preg_match('/(.*?)(\d+)$/', $name, $match);
$base = $match[1];
$num = $match[2]+1;
print $base.$num;
The following will output:
Chicago-Illinos11
However, if it's possible, I'd suggest placing another delimiting character between the text and number. For example, if you placed a pipe, you could simply do an explode and grab the second part of the array. It would be much simpler.
$name = 'Chicago-Illinos|1';
$parts = explode('|', $name);
print $parts[0].($parts[1]+1);
If string length is a concern (thus the misspelling of Illinois), you could switch to the state abbreviations. (i.e. Chicago-IL|1)
$str = 'Chicago-Illinos1';
echo ++$str;
http://php.net/manual/en/language.operators.increment.php

Change input from all upper case into a normal case

I would like to change a string in php from all upper case to normal cases. So that every sentence would start with an upper case and the rest would be in lower case.
Is there a simple way to do this ?
A simple way is to use strtolower to make the string lower case, and ucfirst to upper case the first char as follows:
$str=ucfirst(strtolower($str));
If the string contains multiple sentences, you'll have to write your own algorithm, e.g. explode on sentence separators and process each sentence in turn. As well as the first char, you might need some heuristics for words like "I" and any common proper nouns which appear in your text. E.g, something like this:
$sentences=explode('.', strtolower($str));
$str="";
$sep="";
foreach ($sentences as $sentence)
{
//upper case first char
$sentence=ucfirst(trim($sentence));
//now we do more heuristics, like turn i and i'm into I and I'm
$sentence=preg_replace('/i([\s\'])/', 'I$1', $sentence);
//append sentence to output
$str=$sep.$str;
$sep=". ";
}
Here's a function that will do it:
function sentence_case($s) {
$str = strtolower($s);
$cap = true;
for($x = 0; $x < strlen($str); $x++){
$letter = substr($str, $x, 1);
if($letter == "." || $letter == "!" || $letter == "?"){
$cap = true;
}elseif($letter != " " && $cap == true){
$letter = strtoupper($letter);
$cap = false;
}
$ret .= $letter;
}
return $ret;
}
Source:
http://codesnippets.joyent.com/posts/show/715
I don't know of any method that will do this automatically. You would probably have to write your own with rules that would take of special cases like the letter 'i' needing to be capitalized when it is on its own. You would also still miss out on the ability to capitalize things like people and place names.
Perfectly possible
$s = "THIS IS THE LINE I'M GOING TO WORK ON";
$s = ucfirst(strtolower($s));
echo $s; //This is the line I'm going to work on
If the string contains only 1 sentence then you could use:
$string = ucfirst(strtolower($string));
Point to keep in mind: Do not apply this to all input fields!
People with ALL CAPS initials in their names can get mighty annoyed if you turn "Mike DF King" into "Mike Df King"
cheers :)

Categories