使用PHP DomDocument获取和删除包含specfic id的<p>元素

时间:2016-11-02 20:50:18

标签: php html regex

我有一个用例,我有大量文本(文章正文),我需要识别并删除包含特定文本的两个段落元素。它是我们希望在网页上显示的内容,而不是用于向其他工具提供内容的RSS源。元素看起来像这样:

<p style="text-align: center;"><strong><em><<< Please consider helping us financially with your tax-deductible contribution today >>></em></strong></p>

<p style="text-align: center;"><a href="https://www.example.com/join-the-movement?utm_source=website&amp;utm_campaign=my_campaign&amp;utm_medium=article&amp;utm_term=2016&amp;utm_content=my_utm_content
"><img alt="" class="image-blog_body-100" src="http://www.example.com/s3/files/styles/blog_body-100/s3/images/donatenowbuttonnb.jpg?itok=3h8SQb9v" style="width: 250px; height: 75px;" /></a></p>

我无法通过任何一个特定属性来定位p标记,因此最好的方法是识别块中包含的唯一内容,然后再回去工作。

因此,这可以作为获取箭头之间文本的起点:

<<<\s[a-zA-z\s-]+\s>>>

但我在尝试获取标签之前遇到了麻烦。我显然需要3套开放式支架,标签和关闭支架。在那之后,我可以使用反向引用来获得结束ta。我试过这个

^ [≤(P | EM |强)&GT;] {1,3}&LT;&LT; \ S [A-ZA-Z \ S - ] + \ S取代;&GT;&GT;

但它没有用。我需要更改以获取那些重复标记(以及p标记中的属性文本)?

感谢。

更新:根据@ b.enoit.be的建议,我使用的是PHP DOMDocument。我能够修改插入我需要删除的文本的代码,并且我能够将id值添加到父元素,以便我可以轻松地识别并删除它,例如:

<p id="donateButtonHeading" style="text-align: center;"><strong><em><<< Please consider helping us financially with your tax-deductible contribution today >>></em></strong></p>

getElementById非常适合获取DOMElement对象,但看起来它给了我所有部分内容,我需要得到的是删除它的整个字符串,或者只是从文档中删除整个元素。这就是我尝试的内容($ body是HTML字符串):

$xmlDoc = new DOMDocument();
$xmlDoc->validateOnParse = true;
$xmlDoc->loadHTML($body);
  foreach (array('donateButtonHeading', 'donateButtonMarkup') as $buttonElementId) {
    $buttonElement = $xmlDoc->getElementById($buttonElementId);

  }

我在找出问题的方法是从这里开始。此时$ buttonElement是DOMElement,但我需要从$ xmlDoc中删除它,然后调用$xmlDoc->saveHTML()来获取我的HTML输出。如何让我的DOMElement从$ xmlDoc中删除它?

2 个答案:

答案 0 :(得分:0)

使用phpQueryqueryPath

phpQuery示例:

$html = phpQuery::newDocumentHTML(
    '<div>New Test!!!</div><p style="text-align: center;"><strong><em>&lt;&lt;&lt; Please consider helping us financially with your tax-deductible contribution today &gt;&gt;&gt;</em></strong></p><p>Some paragraph</p>'
);
$html->find('p:contains("Please consider helping us financially with your tax-deductible contribution today")')->remove();
return $html->html();
$html = phpQuery::newDocumentHTML(
    '<p>Entry paragraph</p><p style="text-align: center;"><a href="https://www.example.com/join-the-movement?utm_source=website&amp;utm_campaign=my_campaign&amp;utm_medium=article&amp;utm_term=2016&amp;utm_content=my_utm_content"><img alt="" class="image-blog_body-100" src="http://www.example.com/s3/files/styles/blog_body-100/s3/images/donatenowbuttonnb.jpg?itok=3h8SQb9v" style="width: 250px; height: 75px;" /></a></p><div>This is a test div</div>'
);
$html->find('p a[href*="https://www.example.com/join-the-movement?"')->parent()->remove();
return $html->html();

答案 1 :(得分:-1)

我认为你的表达会更加自由。试试这个:

/(?:<(?:p|strong|em)\s*(?:[a-z]+=".+")?>){1,3}<<<\s*[a-z\s-]+\s*>>>(?:<\/(?:p|strong|em)\s*>){1,3}/gi

请注意,(?:)表示非捕获组。如果要存储标记类型或其他内容,请删除?:,并存储该部分匹配项。您也可以考虑将整个事物包装在匹配的组中,以便可以进一步操作。

https://regex101.com/r/DihfUt/2