【问题标题】:preg_match_all with spacespreg_match_all 带空格
【发布时间】:2012-02-09 19:28:54
【问题描述】:

有一些标题,例如:

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 个示例标题。

有什么想法吗?

【问题讨论】:

  • 如果你想要的话,我有一组这些状态码。
  • 如果每一个都是自己的行/输入,你可以只使用explode()有一个限制:list($http, $status, $msg) = explode(' ', $line, 3);
  • 不需要preg_match_all。有了这个结构,explode 就足够了。

标签: php regex preg-match-all


【解决方案1】:

对于单行和一般文本

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

那么,您是否将每个标题都放在新行上?

【讨论】:

  • 那些“#”字符是什么?那不应该是正斜杠吗?
  • @jperovic 可以是任何东西,只是习惯问题。
  • @jperovic 某些语言需要斜杠,但delimiters in PHP/PCRE “可以是任何非字母数字、非反斜杠、非空白字符。”
【解决方案2】:

您可以为您的正则表达式匹配一个带有(?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

【讨论】:

    【解决方案3】:

    您正在使用几乎很好的正则表达式,但您在字符组定义中缺少[ ](空格),它应该是:/([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 用于转义序列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-23
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多