I've been trying for the couple of days to split a string into letters and numbers. I've found various solutions but they do not work up to my expectations (some of them only separate letters from digits (not integers or float numbers/per say negative numbers).
Here's an example:
$input = '-4D-3A'; // edit: the TEXT part can have multiple chars, i.e. -4AB-3A-5SD
$result = preg_split('/(?<=\d)(?=[a-z])|(?<=[a-z])(?=\d)/i', $input);
print_r($result);
Result:
Array ( [0] => -4 [1] => D-3 [2] => A )
And I need it to be [0] => -4 [1] => D [2] => -3 [3] => A
I've tried doing several changes but no result so far, could you please help me if possible?
Thank you.
try this:
$input = '-4D-3A';
$result = preg_split('/(-?[0-9]+\.?[0-9]*)/i', $input, 0, PREG_SPLIT_DELIM_CAPTURE);
$result=array_filter($result);
print_r($result);
It will split by numbers BUT also capture the delimiter (number)
giving : Array ( [1] => -4 [4] => D [5] => -3 [8] => A )
I've patterened number as:
1. has optional negative sign (you may want to do + too)
2. followed by one or more digits
3. followed by an optional decimal point
4. followed by zero or more digits
Can anyone point out the solution to "-0." being valid number?
How about this regex? ([-]{,1}\d+|[a-zA-Z]+)
I tested it out on http://www.rubular.com/ seems to work as you want.
Related
I tried multiple time to make a pattern that can validate given string is natural number and split into single number.
..and lack of understanding of regex, the closest thing that I can imagine is..
^([1-9])([0-9])*$ or ^([1-9])([0-9])([0-9])*$ something like that...
It only generates first, last, and second or last-second split-numbers.
I wonder what I need to know to solve this problem.. thanks
You may use a two step solution like
if (preg_match('~\A\d+\z~', $s)) { // if a string is all digits
print_r(str_split($s)); // Split it into chars
}
See a PHP demo.
A one step regex solution:
(?:\G(?!\A)|\A(?=\d+\z))\d
See the regex demo
Details
(?:\G(?!\A)|\A(?=\d+\z)) - either the end of the previous match (\G(?!\A)) or (|) the start of string (^) that is followed with 1 or more digits up to the end of the string ((?=\d+\z))
\d - a digit.
PHP demo:
$re = '/(?:\G(?!\A)|\A(?=\d+\z))\d/';
$str = '1234567890';
if (preg_match_all($re, $str, $matches)) {
print_r($matches[0]);
}
Output:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
[8] => 9
[9] => 0
)
I am trying to parse a string that contain strings that are 9-11 characters long and are integers and starts with 08 or +62. How do I do this in PHP? Here's my regex thus far:
/^(\+?62|08)[0-9]{9,11}$/
so here's some sample string/integer I should be able to extract out of a long string
082298744807
087884962429
087783218768
0818809692
081224505277
+628129191929
+62812123929
It's unclear if you want to match numbers between 10-13 digits, or 9-11. In any case it's a simple fix (just count the initial two digits 08, or 62 as part of the total sum of digits. To implement this in php use preg_match_all:
$pat = "/^(?:\+?62|08)[0-9]{8,11}$/uim"; // note modfied range of digits
preg_match_all($pat, $str, $res);
print_r($res[0]);
Example:
http://ideone.com/GJYK7C
Result:
Array
(
[0] => 082298744807
[1] => 087884962429
[2] => 087783218768
[3] => 0818809692
[4] => 081224505277
[5] => +628129191929
[6] => +62812123929
[7] => +629490029944
)
Let's take an example of following string:
$string = "length:max(260):min(20)";
In the above string, :max(260):min(20) is optional. I want to get it if it is present otherwise only length should be returned.
I have following regex but it doesn't work:
/(.*?)(?::(.*?))?/se
It doesn't return anything in the array when I use preg_match function.
Remember, there can be something else than above string. Maybe like this:
$string = "number:disallow(negative)";
Is there any problem in my regex or PHP won't return anything? Dumping preg_match returns int 1 which means the string matches the regex.
Fully Dumped:
int 1
array (size=2)
0 => string '' (length=0)
1 => string '' (length=0)
You're using single character (.) matching in the case of being lazy, at the very beginning. So it stops at the zero position. If you change your preg_match function to preg_match_all you'll see the captured groups.
Another problem is with your Regular Expression. You're killing the engine. Also e modifier is deprecated many many decades before!!! and yet it was used in preg_replace function only.
Don't use s modifier too! That's not needed.
This works at your case:
/([^:]+)(:.*)?/
Online demo
I tried to prepare a regex which can probably solve your issue and also add some value to it
this regex will not only match the optional elements but will also capture in key value pair
Regex
/(?<=:|)(?'prop'\w+)(?:\((?'val'.+?)\))?/g
Test string
length:max(260):min(20)
length
number:disallow(negative)
Result
MATCH 1
prop [0-6] length
MATCH 2
prop [7-10] max
val [11-14] 260
MATCH 3
prop [16-19] min
val [20-22] 20
MATCH 4
prop [24-30] length
MATCH 5
prop [31-37] number
MATCH 6
prop [38-46] disallow
val [47-55] negative
try demo here
EDIT
I think I understand what you meant by duplicate array with different key, it was due to named captures eg. prop & val
here is the revision without named capturing
Regex
/(?<=:|)(\w+)(?:\((.+?)\))?/
Sample code
$str = "length:max(260):min(20)";
$str .= "\nlength";
$str .= "\nnumber:disallow(negative)";
preg_match_all("/(?<=:|)(\w+)(?:\((.+?)\))?/",
$str,
$matches);
print_r($matches);
Result
Array
(
[0] => Array
(
[0] => length
[1] => max(260)
[2] => min(20)
[3] => length
[4] => number
[5] => disallow(negative)
)
[1] => Array
(
[0] => length
[1] => max
[2] => min
[3] => length
[4] => number
[5] => disallow
)
[2] => Array
(
[0] =>
[1] => 260
[2] => 20
[3] =>
[4] =>
[5] => negative
)
)
try demo here
I was wondering how can I create preg_match for catching:
id=4
4 being any number and how can I search for the above example in a string?
If this is could be correct /^id=[0-9]/, the reason why I'm asking is because I'm not really good with preg_match.
for 4 being any number, we must set the range for it:
/^id\=[0-9]+/
\escape the equal-sign, plus after the number means 1 or even more.
You should go with the the following:
/id=(\d+)/g
Explanations:
id= - Literal id=
(\d+) - Capturing group 0-9 a character range between 0 and 9; + - repeating infinite times
/g - modifier: global. All matches (don't return on first match)
Example online
If you want to grab all ids and its values in PHP you could go with:
$string = "There are three ids: id=10 and id=12 and id=100";
preg_match_all("/id=(\d+)/", $string, $matches);
print_r($matches);
Output:
Array
(
[0] => Array
(
[0] => id=10
[1] => id=12
[2] => id=100
)
[1] => Array
(
[0] => 10
[1] => 12
[2] => 100
)
)
Example online
Note: If you want to match all you must use /g modifier. PHP doesn't support it but has other function for that which is preg_match_all. All you need to do is remove the g from the regex.
I have some bar code numbers in an array. PHP seems to be rounding the barcodes which start with leading zeros. How do I stop this happening and keep the numbers as they were? Code I am using is below:
$array = array(5032227448124,5060028999989,5010121096504,5060028999996,5016254104864,5016402052788,8422248036986,0000003798720,0000003735503,0000003798713);
echo '<pre>';
print_r($array);
echo '</pre>';
This echos the following, as you can see the last four bar codes which feature leading zeros have been changed and had their leading zeros removed. These numbers are always 13 digits long and are padded with zeros.
Array
(
[0] => 5032227448124
[1] => 5060028999989
[2] => 5010121096504
[3] => 5060028999996
[4] => 5016254104864
[5] => 5016402052788
[6] => 8422248036986
[7] => 31
[8] => 1030979
[9] => 31
[10] => 1031004
)
You need to quote them as strings if they arent a number (integer, float, exponent).
The obvious, easy, and also likely wrong answer is to make them strings.
The better answer is to use printf()/sprintf() to pad with zeroes:
printf('%013d', 12345); // output: 0000000012345
MySQL also has a handy LPAD() function:
SELECT LPAD(12345, 13, 0) // output 0000000012345
Here's an easy way to convert your values to padded strings:
$array = array_map(function ($e){return str_pad($e, 13, "0", STR_PAD_LEFT);}, $array);
In the end I just needed to put double quotes around each barcode number e.g.
$array = array("5032227448124","5060028999989","5010121096504","5060028999996","5016254104864","5016402052788","8422248036986","0000003798720","0000003735503","0000003798713");