我的正则表达式很差,这是我的情景,
我正在尝试从包含多个表的网页中提取一些信息,只有一些表包含一个唯一的URL(让我们说“very / unique.key”),所以它看起来像这样:
<table ....>
(bunch of content)
</table>
<table ....>
(bunch of content)
</table>
<table ....>
(bunch of content + "very/unique.key" keyword)
</table>
<table ....>
(bunch of content)
</table>
<table ....>
(bunch of content + "very/unique.key" keyword)
</table>
所以我想要的是提取包含“very / unique.key”关键字的所有表的内容。以下是我尝试过的模式:
$pattern = "#<table[^>]+>((?!\<table)(?=very\/unique\.key).*)<\/table>#i";
这对我没有任何回报......
$pattern = "#<table[^>]+>((?!<table).*)<\/table>#i";
即使有<table...>
条件,这也会从表1的开放标记</table>
到最后一个表的结束标记(?!<table)
返回所有内容...
感谢任何愿意帮助我的人,谢谢。
- 的修改 -
以下是我使用DOM循环遍历每个表的解决方案
- 我的解决方案 -
$index;//indexes of all the table(s) that contains the keyword
$cd = 0;//counter
$DOM = new DOMDocument();
$DOM->loadHTMLFile("http://uni.corp/sub/sub/target.php?key=123");
$xpath = new DomXPath($DOM);
$tables = $DOM->getElementsByTagName("table");
for ($n = 0; $n < $tables->length; $n++) {
$rows = $tables->item($n)->getElementsByTagName("tr");
for ($i = 0; $i < $rows->length; $i++) {
$cols = $rows->item($i)->getElementsbyTagName("td");
for ($j = 0; $j < $cols->length; $j++) {
$td = $cols->item($j); // grab the td element
$img = $xpath->query('./img',$td)->item(0); // grab the first direct img child element
if(isset($img) ){
$image = $img->getAttribute('src'); // grab the source of the image
echo $image;
if($image == "very/unique.key"){
echo $cols->item($j)->nodeValue, "\t";
$index[$cd] = $n;
if($n > $cd){
$cd++;
}
echo $cd . " " . $n;//for troubleshooting
}
}
}
echo "<br/>";
}
}
//loop that echo out only the table(s) that I want which contains the keyword
$loop = sizeof($index);
for ($n = 0; $n < $loop; $n++) {
$temp = $index[$n];
$rows = $tables->item($temp)->getElementsbyTagName("tr");
for ($i = 0; $i < $rows->length; $i++) {
$cols = $rows->item($i)->getElementsbyTagName("td");
for ($j = 0; $j < $cols->length; $j++) {
echo $cols->item($j)->nodeValue, "\t";
//proccess the extracted table content here
}
//echo "<br/>";
}
}
但就个人而言,我仍然对Regex部分感到好奇,希望任何人都可以找到这个问题的正则表达式模式的解决方案。无论如何,感谢所有帮助/建议我的人(特别是对AbsoluteƵERØ)。
答案 0 :(得分:2)
这适用于PHP5。我们解析表并使用preg_match()
来检查密钥。您希望使用这样的方法的原因是因为HTML
不必像XML
那样在语法上正确编写。因此,您实际上可能没有正确的结束标记。此外,您可能有嵌套表,这将为您提供多个结果,尝试将开始和结束标记与REGEX匹配。这样我们只检查密钥本身,而不是正在解析的文档的好形式。
<?php
$input = "<html>
<table id='1'>
<tr>
<td>This does not contain the key.</td>
</tr>
</table>
<table id='2'>
<tr>
<td>This does contain the unique.key!</td>
</tr>
</table>
<table id='3'>
<tr>
<td>This also contains the unique.key.</td>
</tr>
</table>
</html>";
$html = new DOMDocument;
$html->loadHTML($input);
$findings = array();
$tables = $html->getElementsByTagName('table');
foreach($tables as $table){
$element = $table->nodeValue;
if(preg_match('!unique\.key!',$element)){
$findings[] = $element;
}
}
print_r($findings);
?>
<强>输出强>
Array
(
[0] => This does contain the unique.key!
[1] => This also contains the unique.key.
)
答案 1 :(得分:1)
虽然我同意你对帖子的评论,但我会给出解决方案。如果你想用其他东西替换这个/ unique.key,正确的正则表达式看起来像这样
#<table(.*)>((.*)very\/unique\.key(.*))<\/table>#imsU
这里的关键是使用正确的修饰符使其适用于您的输入字符串。有关这些修饰符的更多信息,请参阅http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php
现在这里是一个例子,我用“foobar”替换了这个非常/ unique.key
<?php
$string = "
<table ....>
(bunch of content)
</table>
<table ....>
(bunch of content)
</table>
<table ....>
bunch of content very/unique.key
</table>
<table ....>
(bunch of content)
</table>
<table ....>
blabla very/unique.key
</table>
";
$pattern = '#<table(.*)>((.*)very\/unique\.key(.*))<\/table>#imsU';
echo preg_replace($pattern, '<table$1>$3foobar$4</table>', $string);
?>
此代码打印完全相同的字符串,但两个“very / unique.key”替换为“foobar”,就像我们想要的那样。
虽然这个解决方案可行,但它肯定不是效率最高,也不是最简单的方法。就像Mehdi在评论中所说的那样,PHP有一个专门用于操作XML(因此是HTML)的扩展。
以下是该扩展程序文档的链接 http://www.php.net/manual/en/intro.dom.php
使用它,您可以轻松浏览每个表元素并找到具有唯一键的元素。