konakzizu
konakzizu

Reputation: 39

Php preg_split seperates number with comma in two different numbers

$line = "Type:Bid, End Time: 12/20/2018 08:10 AM (PST), Price: $8,000,Bids: 14, Age: 0, Description:  , Views: 120270, Valuation: $10,75, IsTrue: false";

I need to get this array:

Array ( [0] => Bid [1] => 12/20/2018 08:10 AM (PST) [2] => $8,000 [3] => 14 [4] => 0 [5] => [6] => 120270 [7] => $10,75 [8] => false )

Upvotes: 0

Views: 728

Answers (4)

mickmackusa
mickmackusa

Reputation: 47991

I agree with Andreas about using preg_match_all(), but not with his pattern.

For stability, I recommend consuming the entire string from the beginning.

  1. Match the label and its trailing colon. [^:]+:
  2. Match zero or more spaces. \s*
  3. Forget what you matched so far \K
  4. Lazily match zero or more characters (giving back when possible -- make minimal match). .*?
  5. "Look Ahead" and demand that the matched characters from #4 are immediately followed by a comma, then 1 or more non-comma&non-colon character (the next label), then a colon ,[^,:]+: OR the end of the string $.

Code: (Demo)

$line = "Type:Bid, End Time: 12/20/2018 08:10 AM (PST), Price: $8,000,Bids: 14, Age: 0, Description:  , Views: 120270, Valuation: $10,75, IsTrue: false";

var_export(
    preg_match_all(
        '/[^:]+:\s*\K.*?(?=\s*(?:$|,[^,:]+:))/',
        $line,
        $out
    )
    ? $out[0]                        // isolate fullstring matches
    : []                             // no matches
);

Output:

array (
  0 => 'Bid',
  1 => '12/20/2018 08:10 AM (PST)',
  2 => '$8,000',
  3 => '14',
  4 => '0',
  5 => '',
  6 => '120270',
  7 => '$10,75',
  8 => 'false',
)

Upvotes: 2

Toto
Toto

Reputation: 91488

New answer according to new request:

I use he same regex for spliting the string and I replace after what is before the colon:

$line = "Type:Bid, End Time: 12/20/2018 08:10 AM (PST), Price: $8,000,Bids: 14, Age: 0, Description:  , Views: 120270, Valuation: $10,75, IsTrue: false";

$parts = preg_split("/(?<!\d),|,(?!\d)/", $line);
$result = array();
foreach($parts as $elem) {
    $result[] = preg_replace('/^[^:]+:\h*/', '', $elem);
}
print_r ($result);

Output:

Array
(
    [0] => Bid
    [1] => 12/20/2018 08:10 AM (PST)
    [2] => $8,000
    [3] => 14
    [4] => 0
    [5] => 
    [6] => 120270
    [7] => $10,75
    [8] => false
)

Upvotes: 1

user10051234
user10051234

Reputation:

much bettter idea:

$parts=explode(',',$line,4); //explode has a limit you can use in this case 4

same result less code.

I would keep it simple and do this

$line = "TRUE,59,m,10,500";
$parts = preg_split("/,/", $line);

//print_r ($parts);

$parts[3]=$parts[3].','.$parts[4]; //create a new part 3 from 3 and 4
//$parts[3].=','.$parts[4]; //alternative syntax to the above
unset($parts[4]);//remove old part 4
print_r ($parts);

i would also just use explode(), rather than a regular expression.

Upvotes: -1

Andreas
Andreas

Reputation: 23958

I'd use preg_match instead.
Here the pattern looks for digit(s) comma digit(s) or just digit(s) or a word and a comma.

I append a comma to the string to make the regex simpler.

$line = "TRUE,59,m,10,500";

preg_match_all("/(\d+,\d+|\d+|\w+),/", $line . ",", $match);
var_dump($match);

https://3v4l.org/HQMgu

Even with a different order of the items this code will still produce a correct output: https://3v4l.org/SRJOf

Upvotes: 0

Related Questions