5

Consider the following:

700italic
regular
300bold
300bold900

All of those are different examples, only one of the rows will be executed per time.

Expected outcome:

// 700italic
array(
    0 => 700
    1 => itailc
)

// regular
array(
    0 => regular
)

// 300bold
array(
    0 => 300
    1 => bold
)

// 300bold900
array(
    0 => 300
    1 => bold
    2 => 900
)

I made the following:

(\d*)(\w*)

But it's not enough. It kinda works when i only have two "parts" (number|string or string|number) but if i add a third "segment" to it i wont work.

Any suggestions?

4

6 Answers 6

5

You could use preg_split instead. Then you can use lookarounds that match a position between a word an a letter:

$result = preg_split('/(?<=\d)(?=[a-z])|(?<=[a-z])(?=\d)/i', $input);

Note that \w matches digits (and underscores), too, in addition to letters.

The alternative (using a matching function) is to use preg_match_all and match only digits or letters for every match:

preg_match_all('/\d+|[a-z]+/i', $input, $result);

Instead of captures you will now get a single match for every of the desired elements in the resulting array. But you only want the array in the end, so you don't really care where they come from.

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

Comments

1

Could use the PREG_SPLIT_DELIM_CAPTURE flag.

Example:

<?php

$key= "group123425";
$pattern = "/(\d+)/";

$array = preg_split($pattern, $key, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
print_r($array);

?>

Check this post as well.

Comments

1

You're looking for preg_split:

preg_split(
    '((\d+|\D+))', $subject, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
)

Demo

Or preg_match_all:

preg_match_all('(\d+|\D+)', $test, $matches) && $matches = $matches[0];

Demo

Comments

0

You should match it instead of splitting it..

Still you can split it using

(?<=\d)(?=[a-zA-Z])|(?<=[a-zA-Z])(?=\d)

1 Comment

+1 for writing exactly the same solution at pretty much exactly the same time ;)
0

You can use a pattern like this:

(\d*)([a-zA-Z]*)(\d*)

Or you can use preg_match_all with a pattern like this:

'/(?:[a-zA-Z]+|\d+)/'

Then you can match an arbitrary number of segments, each consisting of only letters or only digits.

Comments

0

Maybe something like this:

(\d*)(bold|italic|regular)(\d*)

or

(\d*)([a-zA-Z]*)(\d*)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.