views:

33

answers:

3

I am parsing the input of ls -lb and trying to put each field into an array in PHP.

My input looks something like this:

-rwx------  1 user.name users   546879 2008-09-05 09:23 Newspaper_Templates.pdf
-rwx------  1 user.name users   403968 2009-01-12 14:16 P2_05.ppt
-rwx------  1 user.name users   144896 2009-01-12 14:08 P2.5_Using_CRO.ppt
drwx------  8 user.name users     4096 2009-09-15 10:21 School\ 09-10
drwx------  2 user.name users     4096 2010-06-28 13:59 SMART\ Notebook
drwx------  2 user.name users     4096 2009-11-30 13:35 Templates

I'm looking at each line at a time, and trying to replace multiple spaces with a single space, apart from ones that are escaped with a .

Each row is read into a variable called $filedata, then put through this:

    $filedata = preg_replace("/\s+/", " ", $filedata);
    print_r (preg_split("/[\s]/", $filedata));

This almost works, but for the rows with the escaped spaces, it obviously doesn't. How can I modify this so that my split works for spaces, but not escaped spaces?

(Alternatively, is there a better way? If I could get ls to give me the listing with each field seperated by a comma or something, that would be even better!)

A: 

Try with (?<!\\)\s+

Bundyo
+1  A: 

That is a very error prone way to get file info.

Use the PHP function stat for this purpose.

codaddict
And/or `opendir()` and [`readdir()`](http://php.net/readdir) for "directory listings"
gnarf
Well, it's even worse that you think because I'm using SSH in PHP to connect to a server, run ls then parsing the results in PHP on another server before showing the user...
Rich Bradshaw
A: 

Yes, given that you are using the preg functions, you can use the negative look-behind assertion:

$filedata = preg_replace("/(?<!\\\\)\s+/", " ", $filedata);
print_r(preg_split("/(?<!\\\\)\s/", $filedata));

The (?<!\\\\) gets processed by the PHP string to be (?<!\\) which means test that the character before the white space is not a \

gnarf
Fantastic, though of course I needed it on the split and without the +. (For future readers!) I'll accept in 5 minutes.
Rich Bradshaw