Pad numbers formatted time expression having variable delimiters with leading zeros - php

What is the best way to form a string to a specific format like in excel(##,# etc.)?
I want to set the format like 00:00.00, if someone put 1:10.10 i want to add a zero in front of them.
If the input looks like 1.5.07 it must convert to 01:50.07, harder one: 0.3 must convert to 00:00.30.
I think this is possible with some regex, i can write the expected format but how can i reform the input with this?
$input = "00:13,40";
echo preg_replace("/(d){2}:(d){2}\.(d){2}/","???",$input);
the , in the input must converted to a dot. The input can be "anything" like 13.40 and must converted to 00:13.40. It must replace wrong separator and add missing 0 in front or end (0:13.4)

I don't know if I have enough of a test battery from your question details, but the following technique will correct zero-pad the strings that you have provided.
The pattern effectively parses a string with 2 optional sets of numbers, then a required number before the end of the string.
The pattern allows for any combination of colon, comma, or dots as delimiting characters. If you need more delimiting characters, add them to the character classes.
I added a negative lookahead ((?!\d+$)) to ensure that a number with only two sets of numbers does not use the first set as the hours (first number in the result).
sprintf() is an elegant way of enforcing the zero-padded format in each group of the replacement string.
Code: (Demo)
$tests = [
'1:10.10',
'1.5.07',
'0.3',
'00:13,40',
'15,17',
];
var_export(
preg_replace_callback(
'~(?:(\d{1,2})[:.,](?!\d+$))?(?:(\d{1,2})[:.,])?(\d{1,2})$~',
function($m) {
return sprintf('%02d:%02d.%02d', $m[1], $m[2], $m[3]);
},
$tests
)
);
Output:
array (
0 => '01:10.10',
1 => '01:05.07',
2 => '00:00.03',
3 => '00:13.40',
4 => '00:15.17',
)
Alternatively, you can achieve the same result by loosening the pattern to match digits and non-digits (in an alternating order) and give priority to values that are farther to the right side of the string.
Code: (Demo)
preg_replace_callback(
'~(?:(\d+)\D+)??(?:(\d+)\D+)?(\d+)$~',
function($m) {
unset($m[0]);
return vsprintf('%02d:%02d.%02d', $m);
},
$tests
)

Related

PHP: What is the pattern to find numbers-dashed sub-strings and replace after modification?

I have strings with numbers-dashes sub-strings. I want to find these sub-strings and replace them after some modifications.
For example, the string is like:
This is the string number 123-45-6789-0 which contains 12-34567.
Now I want to find sub-strings of numbers-dashes (123-45-6789-0 and 12-34567) and replace them with the modified sub-strings. For example the final string would be like this:
This is the modified string number 0-6789-45-123 which contains 34567-12.
I have already tried preg_match_all(string $pattern, string $subject, array &$matches) with:
$pattern = '/-*\d+-*/';
but it gives me an array of numbers each one with a dash, like this:
$matches = [123-, 45-, 6789-, 0, 12-, 34567]
whereas, I want an array of two sub-strings, like this:
$matches = [0 => 123-45-6789-0, 1 => 12-34567]
in order to do modifications and replacements (using str_replace()), separately.
Which pattern and methods should I use for these purpose?
Thanks in advance.
You may use \d+(?:-\d+)+ regex with a preg_replace_callback` function:
$str = 'This is the string number 123-45-6789-0 which contains 12-34567.';
echo preg_replace_callback('~\d+(?:-\d+)+~', function($m) {
return implode('-', array_reverse(explode('-', $m[0]))); }
,$str);
// => This is the string number 0-6789-45-123 which contains 34567-12.
See PHP demo and the regex demo.
The \d+(?:-\d+)+ pattern matches
\d+ - 1+ digits
(?:-\d+)+ - 1 or more occurrences of - and 1+ digits sequences.
$m is a match array, $m[0] holds the match value. With explode, the string is split with -, then the array is reversed, and then joined back with implode.

preg_split String into Array at First Non-Numeric Character

I have a string with some numbers and text and I'm trying to split the string at the first non-numeric character.
For Example, I have a few strings like
$value = '150px';
$value = '50em';
$value = '25%';
I've been trying to split the string using preg_split and a little regex.
$value_split = preg_split( '/[a-zA-Z]/' , $fd['yks-mc-form-padding'] );
I'm able to get the first part of the string using $value_split[0], for example I can store 150, or 50 or 25. I need to return the second part of the string as well (px, em or %).
How can I split the string using preg_split or something similar to return both parts of the array??
Thanks!
If you want to use regex and you haven't already, you should play with RegExr.
To do what you're wanting with regex, assuming all the strings will be all numeric together, followed by all non-numeric, you could do:
$matches = array();
preg_match('/([0-9]+)([^0-9]+)/',$value,$matches);
Then $matches[1] will be the numeric part and $matches[2] will be the rest
To break it down,
[0-9] matches any numeric character, so [0-9]+ matches 1 or more numeric characters in a row, so per the docs $matches[1] will have the (numeric) text matched in by the first set of parentheses
and [^0-9] matches any non-numeric character, so [^0-9]+ matches 1 or more non-numeric characters in a row and fills $matches[2] because it's in the 2nd set of parentheses
By preg_split() you cannot achieve what are you trying to. It will delete the part of your string which separates the whole string (in this case it will be separated by character [a-zA-Z]). Use preg_match() (or preg_match_all()) function.
You can use this pattern:
/([0-9]+)([a-zA-Z%]+)/
See demo.
Use the PREG_SPLIT_OFFSET_CAPTURE flag - it will cause an array to be returned, with item [0] being the string matched, and item [1] its starting position in the original string.
You can then use that info to extract the rest of the string by using ordinary sub-string functionality.
Something along the lines of:
$values_split = preg_split( '/[a-zA-Z]/' , $fd['yks-mc-form-padding'] );
$position = $values_split[0][1]
$length = $values_split[0][0]
$startPos = $position + $length
$numToGet = lenght($input) - $startPos
$remainder = substr($inline, startPos, $numToGet)

modify values in variable string with php

Consider example:
$mystring = "us100ch121jp23uk12";
I) I want to change value of jp by adding +1 so that makes the string into
us100ch121jp24uk12
suppose if
II) Is there a way to seperate the numeric part and alphabetic part in the above string into:
[us , 100]
[ch,121]
[jp,24]
[us,12]
my code:
$string = "us100ch121jp23uk12";
$search_for = "us";
$pairs = explode("[]", $string); // I dont know the parameters.
foreach ($pairs as $index=>$pair)
{
$numbers = explode(',',$pair);
if ($numbers[0] == $search_for){
$numbers[1] += 1; // 23 + 1 = 24
$pairs[index] = implode(',',$numbers); //push them back
break;
}
}
$new_string = implode('|',$pairs);
using Evan sir's suggestions
$mystring = "us100ch121jp22uk12";
preg_match_all("/([A-z]+)(\d+)/", $mystring, $output);
//echo $output[0][4];
foreach($output[0] as $key=>$value) {
// echo "[".$value."]";
echo "[".substr($value, 0, 2).",".substr($value, 2, strlen($value) - 2)."]"."<br>";
}
If you use preg_match_all("/([A-z]+)(\d+)/", $string, $output);, it will return an array to $output that contains three arrays. The first array will be country number strings (eg 'us100'). The second will contain country strings (eg 'us'). The third will contain the numbers (eg '100').
Since the second and third arrays will have matching indexes ($output[1][0] will be 'us' and $output[2][0] will be '100'), you could just cycle through those and do whatever you'd like to them.
Here is more information about using regular expressions in PHP. The site also contains information about regular expressions in general, which are a useful tool for any programmer!
You can do it using regular expressions in PHP. See tutorial:
http://w3school.in/w3schools-php-tutorial/php-regular-expression/
Function Description
ereg_replace() The ereg_replace() function finds for string specified by pattern and replaces pattern with replacement if found.
eregi_replace() The eregi_replace() function works similar to ereg_replace(), except that the search for pattern in string is not case sensitive.
preg_replace() The preg_replace() function works similar to ereg_replace(), except that regular expressions can be used in the pattern and replacement input parameters.
preg_match() The preg_match() function finds string of a pattern and returns true if pattern matches false otherwise.
Expression Description
[0-9] It matches any decimal digit from 0 through 9.
[a-z] It matches any character from lowercase a through lowercase z.
[A-Z] It matches any character from uppercase A through uppercase Z.
[a-Z] It matches any character from lowercase a through uppercase Z.
p+ It matches any string containing at least one p.
p* It matches any string containing zero or more p’s.
p? It matches any string containing zero or more p’s. This is just an alternative way to use p*.
p{N} It matches any string containing a sequence of N p’s
p{2,3} It matches any string containing a sequence of two or three p’s.
p{2, } It matches any string containing a sequence of at least two p’s.
p$ It matches any string with p at the end of it.
^p It matches any string with p at the beginning of it.
[^a-zA-Z] It matches any string not containing any of the characters ranging from a through z and A through Z.
p.p It matches any string containing p, followed by any character, in turn followed by another p.
^.{2}$ It matches any string containing exactly two characters.
<b>(.*)</b> It matches any string enclosed within <b> and </b>.
p(hp)* It matches any string containing a p followed by zero or more instances of the sequence hp.
you also can use JavaScript:
http://www.w3schools.com/jsref/jsref_obj_regexp.asp

Split alphanumeric string between leading digits and trailing letters

I have a string like:
$Order_num = "0982asdlkj";
How can I split that into the 2 variables, with the number as one element and then another variable with the letter element?
The number element can be any length from 1 to 4 say and the letter element fills the rest to make every order_num 10 characters long in total.
I have found the php explode function...but don't know how to make it in my case because the number of numbers is between 1 and 4 and the letters are random after that, so no way to split at a particular letter.
You can use preg_split using lookahead and lookbehind:
print_r(preg_split('#(?<=\d)(?=[a-z])#i', "0982asdlkj"));
prints
Array
(
[0] => 0982
[1] => asdlkj
)
This only works if the letter part really only contains letters and no digits.
Update:
Just to clarify what is going on here:
The regular expressions looks at every position and if a digit is before that position ((?<=\d)) and a letter after it ((?=[a-z])), then it matches and the string gets split at this position. The whole thing is case-insensitive (i).
Use preg_match() with a regular expression of (\d+)([a-zA-Z]+). If you want to limit the number of digits to 1-4 and letters to 6-9, change it to (\d+{1,4})([a-zA-Z]{6,9}).
preg_match("/(\\d+)([a-zA-Z]+)/", "0982asdlkj", $matches);
print("Integer component: " . $matches[1] . "\n");
print("Letter component: " . $matches[2] . "\n");
Outputs:
Integer component: 0982
Letter component: asdlkj
http://ideone.com/SKtKs
You can also do it using preg_split by splitting your input at the point which between the digits and the letters:
list($num,$alpha) = preg_split('/(?<=\d)(?=[a-z]+)/i',$Order_num);
You can use a regex for that.
preg_match('/(\d{1,4})([a-z]+)/i', $str, $matches);
array_shift($matches);
list($num, $alpha) = $matches;
Check this out
<?php
$Order_num = "0982asdlkj";
$split=split("[0-9]",$Order_num);
$alpha=$split[(sizeof($split))-1];
$number=explode($alpha, $Order_num);
echo "Alpha -".$alpha."<br>";
echo "Number-".$number[0];
?>
with regards
wazzy
My preferred approach would be sscanf() because it is concise, doesn't need regex, offers the ability to cast the numeric segment as integer type, and doesn't generate needless fullstring matches like preg_match(). %s does rely, though, on the fact that there will be no whitespaces in the letters segment of the string.
Demo
$Order_num = "0982asdlkj";
var_export (
sscanf($Order_num, '%d%s')
);
This can also be set up to declare individual variables.
sscanf($Order_num, '%d%s', $numbers, $letters)
If wanting to use a preg_ function, preg_split() is most appropriate, but I wouldn't use expensive lookarounds. Match the digits, then forget them (with \K). This will split the string without consuming any characters. Demo
var_export (
preg_split('/\d+\K/', $Order_num)
);
To assign variables, use "symmetric array destructuring".
[$numbers, $letters] = preg_split('/\d+\K/', $Order_num);
Beyond these single function approaches, there will be MANY two function approaches like:
$numbers = rtrim($Order_num, 'a..z');
$letters = ltrim($Order_num, '0..9');
But I wouldn't use them in a professional script because they lack elegance.

Split text using multiple delimiters into an array of trimmed values

I've got a group of strings which I need to chunk into an array.
The string needs to be split on either /, ,, with, or &.
Unfortunately it is possible for a string to contain two of the strings which needs to be split on, so I can't use split() or explode().
For example, a string could say first past/ going beyond & then turn, so I am trying to get an array that would return:
array('first past', 'going beyond', 'then turn')
The code I am currently using is
$splittersArray=array('/', ',', ' with ','&');
foreach($splittersArray as $splitter){
if(strpos($string, $splitter)){
$splitString = split($splitter, $string);
foreach($splitString as $split){
I can't seem to find a function in PHP that allows me to do this.
Do I need to be passing the string back into the top of the funnel, and continue to go through the foreach() after the string has been split again and again?
This doesn't seem very efficient.
Use a regular expression and preg_split.
In the case you mention, you would get the split array with:
$splitString = preg_split('/(\/|\,| with |\&/)/', $string);
To concisely write the pattern use a character class for the single-character delimiters and add the with delimiter as a value after the pipe (the "or" character in regex). Allow zero or more spaces on either side of the group of delimiters so that the values in the output don't need to be trimmed.
I am using the PREG_SPLIT_NO_EMPTY function flag in case a delimiter occurs at the start or end of the string and you don't want to have any empty elements generated.
Code: (Demo)
$string = 'first past/ going beyond & then turn with everyone';
var_export(
preg_split('~ ?([/,&]|with) ?~', $string, 0, PREG_SPLIT_NO_EMPTY)
);
Output:
array (
0 => 'first past',
1 => 'going beyond',
2 => 'then turn',
3 => 'everyone',
)

Categories