我正在尝试从字符串中获取重要日期......
<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个不同的正则表达式中获取所有三个日期,请帮助我。感谢
答案 0 :(得分: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
// )
// )
}
But, you shouldn't rely on regex to parse HTML, since HTML isn't a regular language. 此“规则”的一个很好的例外是,如果您的HTML来自您自己的代码,并且您知道可以将其简化为“常规”表达式以进行匹配。 < / p>
答案 1 :(得分:2)
您可以将正则表达式用于这样简单的事情。
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
答案 2 :(得分:2)
“解析”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)<#