Split alphanumeric string between leading digits and trailing letters - php

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.

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.

get the portion of a string between two positions with php

I have a string like "some words 12345cm some more words"
and I want to extract the 12345cm bit from that string. So I get the position of the first number:
$position_of_first_number = strcspn( "some words 12345cm some more words" , '0123456789' );
Then the position of the first space after $position_of_first_number
$position_of_space_after_numbers = strpos("some words 12345cm some more words", " ", $position_of_first_number);
Then I want to have a function which return the portion of the string between $position_of_first_number and $position_of_space_after_numbers.
How do I do it?
You can use the substr function. Note that it takes a starting position and a length, which you can calculate as the difference between the start and end positions.
Since you are looking for a pattern like blank-digits-letters-blank, I would recommend a regular expression using preg_match:
$s = "some words 12345cm some more words";
preg_match("/\s(?P<result>\d+[^\W\d_]+)\s/", $s, $matches);
echo $matches["result"];
12345cm
Explaining the pattern:
"/.../" limits the pattern in PHP
\s matches any whitespace character
(?P<name>...) names the following pattern
\d+ matches 1 or more digits
[^\W\d_]+ matches 1 or more Unicode-letters (i.e. any character that is not a non-alphanumeric character; see this answer)

Return xx characters before a certain string

So I have this string:
Best location using 168 cars + cleaning
The '168' is the part i'd like to extract from this string.
I have approximately 80 occurences of this string, all alternating from 'xx' cars to 'xxx' cars (so, 2 or 3 numbers). However, in each string, 'cars' comes after the number i'd like to return.
What would be the best way using PHP to achieve this?
The best way is to do a simple preg_match on the text.
See the tutorial: http://php.net/manual/en/function.preg-match.php
<?php
$string = 'Best location using 168 cars + cleaning';
$pattern = '/(\d{2,3}+) cars/';
preg_match($pattern, $string, $match);
echo $match[1];
This regex returns all the numbers with length of 2 to 3 before the word cars.
you can change the length as you want and \d means all the numbers.
Easiest way is probably via preg_match(). Look for a space, one or more digits, a space, then the word cars. Use parens to capture the digits. That gives you pattern like this:
' (\d+) cars'
Then just pass that to preg_match() with a third argument to capture the parenthesized substring:
if (preg_match('/ (\d+) cars/', $str, $match)) {
echo "your num is: " . $match[1] . "\n";
}
Note this will also capture 1 cars and 1234 cars. If that's a problem, and you want to ensure that you only get the values with two or three digits, you can tweak the pattern to explicitly require that:
' (\d{2,3}) cars'
I would explode the string on a space and then loop through the array looking for the string "cars" and then get the key value for this. From here you know that the number will be before the "cars" occurrence so minus 1 from this key value and look in the array.
$original_string = "Best location using 168 cars + cleaning";
$string = explode(" ", $original_string);
foreach ($string as $key => $part) {
if($part == "cars") {
$number = $string[$key-1];
}
}
Explanation:
$original_string is whatever your whole string where the number is unknown.
$string is an array of the $original_string, each word will be in it's own part of the array
we loop through this array looking for the string "cars" and also get its key value.
If we find it successfully we then go to the key value minus one to find the number. We do this because we know the number appears before the "cars" string.

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)

Extract last section of string

I have a string like this:
[numbers]firstword[numbers]mytargetstring
I would like to know how is it possible to extract "targetstring" taking account the following :
a.) Numbers are numerical digits for example, my complete string with numbers:
12firstword21mytargetstring
b.) Numbers can be any digits, for example above are two digits each, but it can be any number of digits like this:
123firstword21567mytargetstring
Regardless of the number of digits, I am only interested in extracting "mytargetstring".
By the way "firstword" is fixed and will not change with any combination.
I am not very good in Regex so I appreciate someone with strong background can suggest how to do this using PHP. Thank you so much.
This will do it (or should do)
$input = '12firstword21mytargetstring';
preg_match('/\d+\w+\d+(\w+)$/', $input, $matches);
echo $matches[1]; // mytargetstring
It breaks down as
\d+\w+\d+(\w+)$
\d+ - One or more numbers
\w+ - followed by 1 or more word characters
\d+ - followed by 1 or more numbers
(\w+)$ - followed by 1 or more word characters that end the string. The brackets mark this as a group you want to extract
preg_match("/[0-9]+[a-z]+[0-9]+([a-z]+)/i", $your_string, $matches);
print_r($matches);
You can do it with preg_match and pattern syntax.
$string ='2firstword21mytargetstring';
if (preg_match ('/\d(\D*)$/', $string, $match)){
// ^ -- end of string
// ^ -- 0 or more
// ^^ -- any non digit character
// ^^ -- any digit character
var_dump($match[1]);}
Try it like,
print_r(preg_split('/\d+/i', "12firstword21mytargetstring"));
echo '<br/>';
echo 'Final string is: '.end(preg_split('/\d+/i', "12firstword21mytargetstring"));
Tested on http://writecodeonline.com/php/
You don't need regex for that:
for ($i=strlen($string)-1; $i; $i--) {
if (is_numeric($string[$i])) break;
}
$extracted_string = substr($string, $i+1);
Above it's probably the faster implementation you can get, certainly faster than using regex, which you don't need for this simple case.
See the working demo
your simple solution is here :-
$keywords = preg_split("/[\d,]+/", "hypertext123language2434programming");
echo($keywords[2]);

Categories