Reputation: 2275
have some headers like:
HTTP/1.1 100 Continue
HTTP/1.1 302 Found
HTTP/1.1 200 OK
HTTP/1.1 400 Not Found
so, I need to get 2 parts:
[200] => [OK]
[400] => [Not Found]
I need a way to use preg_match_all
and get those values, but need to preserve the spaces at Not Found
have this code:
preg_match_all( '/([0-9]{3}) ([A-Za-z0-9+]*)/', $headers, $matches );
Works with 1-3 example headers.
Any ideas?
Upvotes: 1
Views: 2475
Reputation: 20540
You can give your regex matches a name with (?P<name>)
, making your code more readable. also you can go with a much easier regex:
preg_match('#HTTP/1\.\d (?P<code>\d{3}) (?P<text>.*)#', $str, $matches);
echo $matches['code']; // 2100", same as $matches[1]
echo $matches['text']; // "Continue", same as $matches[2]
preg_match_all('#HTTP/1\.\d (?P<code>\d{3}) (?P<text>.*)#', $str, $matches, PREG_SET_ORDER);
echo $matches[0]['code']; // 100
echo $matches[0]['text']; // Continue
echo $matches[3]['code']; // 404
echo $matches[3]['text']; // Not Found
or even more simple, without regex using explode()
:
list(,$code,$text) = explode(" ", $str, 3); // works only on a single status line
echo $code; // 100
echo $text; // Continue
Upvotes: 3
Reputation: 20997
You are using almost good regexp but you're missing [ ]
(space) from the character group definition, it should be: /([0-9]{3}) ([A-Za-z0-9 +]*)/
.
Or rather use
\w
instead of [A-Za-z]
\d
instead of [0-9]
and\s
instead of [ ]
So your patter would look like:
/(\d{3}) ([\w\d\s+]*)/
And make sure it won't match something it shouldn't
/HTTP\/1\.\d (\d{3}) ([\w\d\s+]+)/
So whole code would look like:
preg_match_all( '/HTTP\/1\.\d (\d{3}) ([\w\d\s+]+)/', $headers, $matches );
Here's an explanation for escape sequences.
Upvotes: 2
Reputation: 16214
For the single line and for the text in general
$str = "HTTP/1.1 100 Continue
HTTP/1.1 302 Found
HTTP/1.1 200 OK
HTTP/1.1 400 Not Found";
// for the values in the string, one on each line
preg_match_all('#(\d{3})\s+([\w\s]+)$#m', $str, $matches);
var_dump($matches); // captures a new line symbol if exists
// for single value in the string
$str = "HTTP/1.1 400 Not Found";
preg_match('#(\d{3})\s+([\w\s]+)$#', $str, $matches);
var_dump($matches);
So, do you have each header on a new line or not?
Upvotes: 3