qwerty
qwerty

Reputation: 5246

Regex: Split string on number/string?

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?

Upvotes: 5

Views: 4977

Answers (6)

hakre
hakre

Reputation: 197767

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

Upvotes: 1

Zemistr
Zemistr

Reputation: 1049

Maybe something like this:

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

or

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

Upvotes: 0

SeanWM
SeanWM

Reputation: 16989

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.

Upvotes: 1

dan1111
dan1111

Reputation: 6566

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.

Upvotes: 0

Anirudha
Anirudha

Reputation: 32797

You should match it instead of splitting it..

Still you can split it using

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

Upvotes: 0

Martin Ender
Martin Ender

Reputation: 44259

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.

Upvotes: 5

Related Questions