TD 中的 PHP 正则表达式,当有日期和时间时


php regular expression in td when have date and time

我需要使用 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 中的文本可以具有像 &gt; 这样的实体(可以用 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
    )
)