我正在尝试从字符串中获取重要日期...
<tr> <td>Account Registered :</td> <td>2008-02-02</td></tr>
<tr> <td>Account Updated :</td> <td>2014-02-01</td></tr>
<tr> <td>Account Expires :</td> <td>2015-02-02</td></tr>
我已经尝试了以下...
preg_match('#<tr> <td>Account Expires :</td> <td>[0-9]{4}-[0-9]{2}-[0-9]{2}#', $result, $matches);
它提供以下...
array (size=1)
0 => string '<tr> <td>Account Expires :</td> <td>2015-02-02' (length=38)
我想在 1 个正则表达式或 3 个不同的正则表达式中获取所有三个日期,请帮助我。
您可以使用
()
来设置可在preg_match_all()
中访问的捕获组(与preg_match()
不同,它执行全局匹配(。那么你只需要不指定动词Expires
:
$result = '
<tr> <td>Account Registered :</td> <td>2008-02-02</td></tr>
<tr> <td>Account Updated :</td> <td>2014-02-01</td></tr>
<tr> <td>Account Expires :</td> <td>2015-02-02</td></tr>
';
if(preg_match_all('#<tr>'s*<td>Account's*([^:]*?)'s*:</td>'s*<td>([0-9]{4}-[0-9]{2}-[0-9]{2})#', $result, $matches, PREG_SET_ORDER)) {
print_r($matches);
// Array
// (
// [0] => Array
// (
// [0] => <tr> <td>Account Registered :</td> <td>2008-02-02
// [1] => Registered
// [2] => 2008-02-02
// )
//
// [1] => Array
// (
// [0] => <tr> <td>Account Updated :</td> <td>2014-02-01
// [1] => Updated
// [2] => 2014-02-01
// )
//
// [2] => Array
// (
// [0] => <tr> <td>Account Expires :</td> <td>2015-02-02
// [1] => Expires
// [2] => 2015-02-02
// )
// )
}
但是,你不应该依赖正则表达式来解析 HTML,因为 HTML 不是一种常规语言。这个"规则"的一个很好的例外是,如果你的HTML来自你自己的代码,并且你知道你可以将其简化为"正则"表达式进行匹配。
您可以将正则表达式用于像这样简单的事情。
preg_match_all('/'b'd{4}-'d{2}-'d{2}'b/', $html, $matches);
print_r($matches[0]);
但我建议使用诸如 DOM
之类的解析器来提取这些值。
// Load your HTML
$dom = DOMDocument::loadHTML('
<tr> <td>foo bar</td> <td>123456789</td></tr>
<tr> <td>Account Registered :</td> <td>2008-02-02</td></tr>
<tr> <td>Account Updated :</td> <td>2014-02-01</td></tr>
<tr> <td>Account Expires :</td> <td>2015-02-02</td></tr>
<tr> <td>something else</td> <td>foo</td></tr>
');
$xp = new DOMXPath($dom);
$tag = $xp->query('//tr/td[contains(.,"Account")]/following-sibling::*[1]');
foreach($tag as $t) {
echo $t->nodeValue . "'n";
}
// 2008-02-02
// 2014-02-01
// 2015-02-02
如果您不确定前缀的要求,即(Account
可能会更改(,简单的解决方法是验证。
$xp = new DOMXPath($dom);
$tag = $xp->query('//tr/td/following-sibling::*[1]');
foreach($tag as $t) {
$date = date_parse($t->nodeValue);
if ($date["error_count"] == 0 &&
checkdate($date["month"], $date["day"], $date["year"])) {
echo $t->nodeValue . "'n";
}
}
// 2008-02-02
// 2014-02-01
// 2015-02-02
用于"解析"HTML的简单正则表达式很好。它可能比使用 DOM 解析器更快、更面向未来。
这个捕获所有"标签内的日期":
preg_match_all('#>('d'd'd'd-'d'd-'d'd)<#', $html, $matches);
$dates = $matches[1];
print_r($dates);
使:
Array
(
[0] => 2008-02-02
[1] => 2014-02-01
[2] => 2015-02-02
)
如果$html
中有更多的日期,而您只想要这 3 个日期,请忘记这个答案。
如果要在日期(时间(戳中包含时间,请使用以下模式:
#>('d'd'd'd-'d'd-'d'd 'd'd:'d'd:'d'd)<#