带空格的preg_match_all

时间:2012-02-09 19:28:54

标签: php regex preg-match-all

有一些标题如:

HTTP/1.1 100 Continue
HTTP/1.1 302 Found
HTTP/1.1 200 OK
HTTP/1.1 400 Not Found

所以,我需要得到2个部分:

[200] => [OK]
[400] => [Not Found]

我需要一种方法来使用preg_match_all并获取这些值,但需要保留Not Found处的空格

有这段代码:

preg_match_all( '/([0-9]{3}) ([A-Za-z0-9+]*)/', $headers, $matches );

使用1-3个示例标题。

有什么想法吗?

3 个答案:

答案 0 :(得分:3)

对于单行和一般文本

$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);

那么,你是否在新行上有每个标题?

答案 1 :(得分:3)

您可以为正则表达式匹配一个名称(?P<name>),使您的代码更具可读性。你也可以使用更简单的正则表达式:

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

或更简单,没有正则表达式使用explode()

list(,$code,$text) = explode(" ", $str, 3); // works only on a single status line
echo $code; // 100
echo $text; // Continue

答案 2 :(得分:2)

你正在使用几乎好的正则表达式,但是你从字符组定义中缺少[ ](空格),它应该是:/([0-9]{3}) ([A-Za-z0-9 +]*)/

或者更确切地说使用

  • \w代替[A-Za-z]
  • \d代替[0-9]
  • \s代替[ ]

所以你的模式看起来像:

/(\d{3}) ([\w\d\s+]*)/

并确保它不匹配不应该

的东西
/HTTP\/1\.\d (\d{3}) ([\w\d\s+]+)/

所以整个代码看起来像:

preg_match_all( '/HTTP\/1\.\d (\d{3}) ([\w\d\s+]+)/', $headers, $matches );

Here's an explanation表示转义序列。