25

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.

0

6 Answers 6

35

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).

Sign up to request clarification or add additional context in comments.

20 Comments

What's the advantage of using split over match?
You need to escape the \ in \d.
@marcog: Good question... I was just focused on splitting the string ;) I'm not sure whether there is any advantage.
@Col. Shrapnel: There is not always the only true answer to a problem. People think in different ways. And knowing different ways to solve a problem is even better!
The discussion is over anyway. All I wanted is to show one way of doing it. It is not my fault that the OP accepted the answer. If some of you guys want to have the-only-one-and-true-solution then go and live in a Brave new World. Don't forget that the answers are not only for the person who asks but also for those who come after...
|
7

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

5 Comments

$matches = array(); is not really needed. preg_match will ensure that the array will alway exist, even when there is no match.
Also you need not escape \ in \\d+. \d+ is enough.
@codaddict: But it is good coding style and easier to understand for the less proficient PHP programmer IMO.
@codaddict Didn't know about the array(), but I don't like not escaping.
Or use this even simpler expression: /(\d+)(.*)/
5

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);

Comments

2

You can use a regex for that.

preg_match('/(\d{1,4})([a-z]+)/i', $str, $matches);
array_shift($matches);
list($num, $alpha) = $matches;

1 Comment

I won't use strict limit on the number but beside that it's most sensible answer.
0

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

4 Comments

Upgrade your PHP from the ancient version to something modern and run it again
@Wazzy: Because people are crazy and downvote answers they don't like. To be fair, your solution is not very elegant, but it gives the right solution. I would not upvote it, but I would not downvote either. +1 from my to compensate.
@Col. Shrapnel: Works fine with PHP 5.3.3
@Col. Shrapnel: So split is deprecated in PHP 5.3 and can be replaced by preg_split... it still with split or preg_split it works. I'm against downvoting without explanation and Upgrade your PHP from the ancient version to something modern and run it again is not an explanation.
0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.