我需要使用 reg exp 提取日期和时间,但不起作用,我不知道为什么?
<tr>
<td align="center">13.44.333-3</td>
<td align="center">asdf3</td>
<td align="center">15/01/2016 00:22:16</td>
<td align="center">$ 1531</td>
</tr>
<tr>
<td align="center">13.333.333-3</td>
<td align="center">asdf3</td>
<td align="center">16/01/2016 00:22:16</td>
<td align="center">$ 1531</td>
</tr>
<tr>
<td align="center">13.333.333-3</td>
<td align="center">asdf3</td>
<td align="center">11/01/2015 00:22:16</td>
<td align="center">$ 1531</td>
</tr>
我使用的注册经验:
preg_match_all("/<td align='"center'"'>['s]*([^'s'<'/]*)<'/td>['s]*<td align='"center'"'>/is",$content, $matches, null, 0);
结果是 : 11/01/2016
但我需要这个: 11/01/2016 11:59:49
我不知道我做错了。
我需要的结果是:
array (
0 =>
array (
0 => '<td align="center">15/01/2016 00:22:16</td>
<td align="center">',
1 => '<td align="center">11/01/2015 00:22:16</td>
<td align="center">',
),
1 =>
array (
0 => '15/01/2016 00:22:16',
1 => '11/01/2015 00:22:16',
),
)
这是一个解析器/正则表达式方法:
$html = '<tr>
<td align="center">13.333.333-3</td>
<td align="center">asdf3</td>
<td align="center">15/01/2016 00:22:16</td>
<td align="center">$ 1531</td>
</tr>';
$thedoc = new DOMDocument();
$thedoc->loadHTML($html);
$cells = $thedoc->getElementsByTagName('td');
foreach($cells as $cell){
if(preg_match('~^('d{2}/'d{2}/'d{4})'h('d{2}:'d{2}:'d{2})$~', $cell->nodeValue, $matches)) {
echo 'Date:' . $matches[1] . ' Time:'. $matches[2];
}
}
PHP 演示:https://eval.in/515935
正则表达式101演示:https://regex101.com/r/sT2hD9/1
这也将允许无效的时间/日期,但它们必须正确格式化,例如 22/22/2222 25:61:62
.根据要求,您可以使其工作,如果需要,也可以使零件(秒(可选。您还可以将日、月、年、小时、分钟和秒分别分组。
使用适当的 DOM 解析器解析 HTML 比在其上使用正则表达式更好,因此我将首先给出该解决方案:
1. 使用多姆
为此,将 DOMDocument 与 DOMXPath 结合使用。
下面是仅获取包含日期/时间的第三列内容的代码:
$doc = new DOMDocument();
$doc->loadHTML($html);
$xpath = new DOMXPath($doc);
$elements = $xpath->query('//td[3]');
$matches = array_map(function($td) {
return $td->textContent;
}, iterator_to_array($elements));
此代码将执行 XPath 查询,在给定的 HTML 中查找 td 元素,这些元素是其各自父级 (tr( 的第三个子元素,然后将找到的每个 td 的文本内容映射到数组中。
如果 $html 变量具有以下字符串:
<table width="100%" border="0" cellspacing="0" cellpadding="0" id="facturas">
<tr>
<td align="center">13.44.333-3</td>
<td align="center">asdf3</td>
<td align="center">15/01/2016 00:22:16</td>
<td align="center">$ 1531</td>
</tr>
<tr>
<td align="center">13.333.333-3</td>
<td align="center">asdf3</td>
<td align="center">16/01/2016 00:22:16</td>
<td align="center">$ 1531</td>
</tr>
<tr>
<td align="center">13.333.333-3</td>
<td align="center">asdf3</td>
<td align="center">11/01/2015 00:22:16</td>
<td align="center">$ 1531</td>
</tr>
</table>
然后$matches将是以下数组:
array (
'15/01/2016 00:22:16',
'16/01/2016 00:22:16',
'11/01/2015 00:22:16',
)
请参阅在 eval.in 上输出运行的代码。
一些替代的 XPath 查询:
如果$html可以有其他表,则应将搜索限制为感兴趣的表,例如,id 等于 facturas:
//*[@id="facturas"]//td[3]
要确保每个匹配的 td 都将对齐属性设置为"中心">,请执行以下操作:
//td[@align="center"]
要查找具有特定文本(如"/2016"(的元素,请执行以下操作:
//td[contains(., "/2016")]
2. 使用正则表达式
尽管不建议这样做,但您可以使用正则表达式。
如果您仍然想这样做,请使用以下代码:
preg_match_all("/<td[^>]*'>'s*('d'd'/'d'd'/'d{4}'b[^<]*)<'/td's*>/mis",
$html, $matches);
这将匹配包含以格式为"99/99/9999">的文本开头的值的 td 元素(9 可以是任何数字(。
现在$matches将是:
array (
0 =>
array (
0 => '<td align="center">15/01/2016 00:22:16</td>',
1 => '<td align="center">16/01/2016 00:22:16</td>',
2 => '<td align="center">11/01/2015 00:22:16</td>',
),
1 =>
array (
0 => '15/01/2016 00:22:16',
1 => '16/01/2016 00:22:16',
2 => '11/01/2015 00:22:16',
),
)
查看在 eval.in 上输出运行的代码
但请注意,一般来说,HTML 中的文本可以具有像 >
这样的实体(可以用 html_entity_decode 解决(,或者 td 元素可以包含<br>
或其他标签(有时可以用 strip_tags 解决(,或者标签属性可以具有包含 HTML 的值,这可能会欺骗正则表达式。脚本标签也是如此,它可能具有在变量中包含HTML字符串的JavaScript。
这些只是例子。可能导致此类正则表达式出错的事情列表很长。在使用 DOM 解析器时,所有这些都不是问题,但是使用正则表达式,几乎不可能在所有可能的情况下获得正确的方法。
因此,解决方案1是要选择的解决方案。
你有没有找到解决方案,我希望提供帮助。
<?php
$html=<<<HEREDOC
<tr>
<td align="center">13.44.333-3</td>
<td align="center">asdf3</td>
<td align="center">15/01/2016 00:22:16</td>
<td align="center">$ 1531</td>
</tr>
<tr>
<td align="center">13.333.333-3</td>
<td align="center">asdf3</td>
<td align="center">16/01/2016 00:22:16</td>
<td align="center">$ 1531</td>
</tr>
<tr>
<td align="center">13.333.333-3</td>
<td align="center">asdf3</td>
<td align="center">11/01/2015 00:22:16</td>
<td align="center">$ 1531</td>
</tr>
HEREDOC;
if(preg_match_all('~<td's+[^>]*>((?:'d+(?:'/'d+){2})'s+(?:'d+(?:':'d+){2}))<'/td>~mi',$html,$matchall)){
print_r($matchall);
}
?>
输出将是
Array
(
[0] => Array
(
[0] => <td align="center">15/01/2016 00:22:16</td>
[1] => <td align="center">16/01/2016 00:22:16</td>
[2] => <td align="center">11/01/2015 00:22:16</td>
)
[1] => Array
(
[0] => 15/01/2016 00:22:16
[1] => 16/01/2016 00:22:16
[2] => 11/01/2015 00:22:16
)
)