Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make this weird string explode in PHP?

Tags:

regex

grep

php

I have a string like the following

DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]

The above string is a kind of formatted in groups that looks like the following:

A-B[C]-D-E-[F]-G-[H]

The think is that I like to process some of those groups, and I like to make something like explode.

I say like, because I have try this code:

$string = 'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]';
$parts = explode( '-', $string );
print_r( $parts );

and I get the following result:

Array
(
    [0] => DAS
    [1] => 1111[DR
    [2] => Helpfull
    [3] => R]
    [4] => RUN
    [5] => 
    [6] => [121668688374]
    [7] => N
    [8] => [+helpfull_+string]
)

that it is not what I need.

What I need is the following output:

Array
(
    [0] => DAS
    [1] => 1111[DR-Helpfull-R]
    [2] => RUN
    [3] => 
    [4] => [121668688374]
    [5] => N
    [6] => [+helpfull_+string]
)

Can someone please suggest a nice and elegant way to explode this string in the way I need it ?

what I forgot to mention, is that the string can have more or less groups. Examples:

DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]
DAS-1111[DR-Helpfull-R]-RUN--[121668688374]
DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]-anotherPart

Update 1

As mentioned by @axiac, the preg_split can do the work. But can you please help with the regex now ?

I have try this but it seems that it is incorrect:

(?!\]\-)\-

like image 535
KodeFor.Me Avatar asked Apr 15 '16 11:04

KodeFor.Me


People also ask

What does explode () do in PHP?

The explode() function breaks a string into an array. Note: The "separator" parameter cannot be an empty string. Note: This function is binary-safe.

Why explode () is used?

The explode function is utilized to "Split a string into pieces of elements to form an array". The explode function in PHP enables us to break a string into smaller content with a break. This break is known as the delimiter.

How convert string to array in PHP with explode?

Explode MethodPass a delimiter and a string to the explode function, and it splits the string into array elements, where it finds the delimiter. The delimiter can be a single character or it can be multiple characters.

What is implode in PHP?

The implode() is a builtin function in PHP and is used to join the elements of an array. implode() is an alias for PHP | join() function and works exactly same as that of join() function. If we have an array of elements, we can use the implode() function to join them all to form one string.


2 Answers

The code:

$str = 'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]';
$re  = '/([^-[]*(?:\[[^\]]*\])?[^-]*)-?/';

$matches = array();
preg_match_all($re, $str, $matches);
print_r($matches[1]);

Its output:

Array
(
    [0] => DAS
    [1] => 1111[DR-Helpfull-R]
    [2] => RUN
    [3] =>
    [4] => [121668688374]
    [5] => N
    [6] => [+helpfull_+string]
    [7] =>
)

There is an extra empty value at position 7 in the output. It appears because of the zero-or-one repetitions quantifier (?) placed at the end of the regex. The quantifier is needed because without it the last piece (at index 6) is not matched.

You can remove the ? after the last - and ask this way the dash (-) always match. In this case you must append an extra - to your input string.

The regex

(              # start of the 1st subpattern
               # the captured value is returned in $matches[1]
  [^-[]*       # match any character but '-' and '[', zero or more times
  (?:          # start of a non-capturing subpattern
    \[         # match an opening square bracket ('[')
    [^\]]*     # match any character but ']', zero or more times
    \]         # match a closing square bracket (']')
  )?           # end of the subpattern; it is optional (can appear 0 or 1 times)
  [^-]*        # match any character but '-', zero or more times
)              # end of the 1st subpattern
-?             # match an optional dash ('-')
like image 56
axiac Avatar answered Sep 26 '22 08:09

axiac


Instead of exploding you should try to match the following pattern:

(?:^|-)([^-\[]*(?:\[[^\]]+\])?)

Here is an example:

$regex = '/(?:^|-)([^-\[]*(?:\[[^\]]+\])?)/';
$tests = array(
    'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]',
    'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]',
    'DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]-anotherPart'
);
foreach ($tests as $test) {
    preg_match_all($regex, $test, $result);
    print_r($result[1]);
}

Output:

// DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]
Array
(
    [0] => DAS
    [1] => 1111[DR-Helpfull-R]
    [2] => RUN
    [3] => 
    [4] => [121668688374]
    [5] => N
    [6] => [+helpfull_+string]
)

// DAS-1111[DR-Helpfull-R]-RUN--[121668688374]
Array
(
    [0] => DAS
    [1] => 1111[DR-Helpfull-R]
    [2] => RUN
    [3] => 
    [4] => [121668688374]
)

// DAS-1111[DR-Helpfull-R]-RUN--[121668688374]-N-[+helpfull_+string]-anotherPart
Array
(
    [0] => DAS
    [1] => 1111[DR-Helpfull-R]
    [2] => RUN
    [3] => 
    [4] => [121668688374]
    [5] => N
    [6] => [+helpfull_+string]
    [7] => anotherPart
)
like image 42
Salman A Avatar answered Sep 25 '22 08:09

Salman A