1

I'm using regex in preg_split to split a string into separate parts.

$string = 'text required name="first_name" label="First Name" column="1/2"';
$ps = preg_split("/\s(?![\w\s]+\")/u", $string);
echo '<pre>',print_r($ps,1),'</pre>';

The above code gives the following result and is working correctly:

Array
(
[0] => text
[1] => required
[2] => name="first_name"
[3] => label="First Name"
[4] => column="1/2"
)

But if I add any special characters inside the double quotemarks the string is broken down into separate array items:

$string = 'text required name="first_name" label="First Name! $ , ." column="1/2"';
$ps = preg_split("/\s(?![\w\s]+\")/u", $string);
echo '<pre>',print_r($ps,1),'</pre>';

Resulting in:

Array
(
[0] => text
[1] => required
[2] => name="first_name"
[3] => label="First
[4] => Name!
[5] => $
[6] => ,
[7] => ."
[8] => column="1/2"
)

How can I keep "First Name! $ , ." in the same array item?

e.g. like this:

Array
(
[0] => text
[1] => required
[2] => name="first_name"
[3] => label="First Name! $ , ."
[4] => column="1/2"
)
The Bobster
  • 573
  • 4
  • 20

2 Answers2

2

You may use this regex for splitting:

"[^"\\]*(?:\\.[^"\\]*)*"(*SKIP)(*F)|\h+

Code:

php > $string = 'text required name="first_name" label="First Name! \"$ , ." column="1/2"';
php > $re = '/"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"(*SKIP)(*F)|\h+/';
php > print_r( preg_split($re, $string) );
Array
(
    [0] => text
    [1] => required
    [2] => name="first_name"
    [3] => label="First Name! \"$ , ."
    [4] => column="1/2"
)

RegEx Demo

RegEx Explanation:

  • "[^"\\]*(?:\\.[^"\\]*)*": Match a quotes string that may include escaped characters
  • (*SKIP)(*F): Skip and fail this match
  • |: OR
  • \h+: Match 1+ whitespace
anubhava
  • 761,203
  • 64
  • 569
  • 643
0

I would use preg_match_all here with the following alternation:

\w+=\".*?\"|\b\w+(?!\S)

This pattern will attempt to match a key="value" entry. That failing, it will try to match a standalone word which is followed either by whitespace or is the last word in the input.

PHP code:

$input = 'text required name="first_name" label="First Name! $ , ." column="1/2"';
preg_match_all("/\w+=\".*?\"|\b\w+(?!\S)/", $input, $matches);
print_r($matches);

This prints:

Array
(
    [0] => text
    [1] => required
    [2] => name="first_name"
    [3] => label="First Name! $ , ."
    [4] => column="1/2"
)
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360