试图学习为PHP编写RegEx

时间:2015-04-21 00:22:55

标签: php regex datetime

我正在尝试学习如何编写RegEx,但似乎所有搜索都会导致信息不清楚。所以我的问题是双重的。

  1. 有没有人知道新手如何学会写RegExs?
  2. 我怎么能写一个将字符串1y 311d 16h 42m分解为变量的RegEx?
  3. 我正在寻找上面的文本字符串并将其分解为:

    $duration[years] = 1;
    $duration[days] = 311;
    $duration[hours] = 16;
    $duration[minutes] = 42;
    

    请注意,总数字可能并不总是相同,例如可能是两位数天。就像是。可以省略25d或一些。我可能会得到几天和几个小时。最后,订单可能会改变。也许这是几天以后写的等等。

    我知道我可以使用爆炸功能和strpos轻松完成这项工作,但我真的想学习正则表达式,所以我使用它作为一个例子,因为我知道它们对于这样的事情非常强大。

1 个答案:

答案 0 :(得分:2)

1)一些有用的页面:

2)具体来说,这是:

$pattern = '/(?:(?P<years>\d+)y\s*)?(?:(?P<days>\d+)d\s*)?(?:(?P<hours>\d+)h\s*)?(?:(?P<minutes>\d+)m\s*)?/';
preg_match($pattern, '1y 311d 16h 42m', $duration);
print_r($duration);
// Array
// (
//     [0] => 1y 311d 16h 42m
//     [years] => 1
//     [1] => 1
//     [days] => 311
//     [2] => 311
//     [hours] => 16
//     [3] => 16
//     [minutes] => 42
//     [4] => 42
// )
preg_match($pattern, '311d 42m', $duration);
print_r($duration);
// Array
// (
//     [0] => 1y 311d 16h 42m
//     [years] =>
//     [1] =>
//     [days] => 311
//     [2] => 311
//     [hours] =>
//     [3] =>
//     [minutes] => 42
//     [4] => 42
// )

这会给出固定的顺序。如果订单可以更改,regexp不是一个好工具。在这种情况下仍然可能,但相当尴尬。这是:

$pattern = "/(?=.*?(?:(?P<years>\d+)y|$))(?=.*?(?:(?P<days>\d+)d|$))(?=.*?(?:(?P<hours>\d+)h|$))(?=.*?(?:(?P<minutes>\d+)m|$))/";    
preg_match($pattern, '311d 16h 1y', $duration);
print_r($duration);
// Array
// (
//     [0] =>
//     [years] => 1
//     [1] => 1
//     [days] => 311
//     [2] => 311
//     [hours] => 16
//     [3] => 16
// )

在regex101中输入这些模式(不带前导和斜杠)可以解释它究竟要匹配的内容。从regex tag questions中查找其他示例并输入它们,并尝试查看它们的工作原理。经验是最好的老师。