从字符串中删除带哈希符号的链接

时间:2018-01-08 01:00:01

标签: php regex url

我有一个包含HTML内容的数据库,它有一些带链接的文本。有些文本的URL中有哈希符号,有些则没有。

我需要删除带有哈希符号的链接,并保留带有哈希符号的链接。

示例:

输入:

<a href="http://example.com/books/1">The Lord of the Rings</a>
<ul>
    <li><a   href="http://example.com/books/1#c1" >Chapter 1</a></li>
    <li><a name="name before href" href="http://example.com/books/1#c2">Chapter 2</a></li>
    <li><a href="http://example.com/books/1#c3" name="name after href">Chapter 3</a></li>
    <li><a href="http://example.com/books/1#cN" target="_blank">Chapter N</a></li>
</ul>
<br><br>
<a href="http://example.com/books/1">Harry Potter</a>
<ul>
    <li><a href="http://example.com/books/2#c1" target="_self">Chapter 1</a></li>
    <li><a href="http://example.com/books/2#c2" name="some have name" title="some others have title" >Chapter 2</a></li>
    <li><a href="http://example.com/books/2#c3">Chapter 3</a></li>
    <li><a href="http://example.com/books/2#cN"  >Chapter N</a></li>
</ul>

期望的输出:

<a href="http://example.com/books/1">The Lord of the Rings</a>
<ul>
    <li>Chapter 1</li>
    <li>Chapter 2</li>
    <li>Chapter 3</li>
    <li>Chapter N</li>
</ul>
<br><br>
<a href="http://example.com/books/2">Harry Potter</a>
<ul>
    <li>Chapter 1</li>
    <li>Chapter 2</li>
    <li>Chapter 3</li>
    <li>Chapter N</li>
</ul>

我正在尝试使用此代码,但它删除了所有链接,我想保留那些没有哈希符号的链接。

$content = preg_replace('#<a.*?>([^>]*)</a>#i', '$1', $content);

所以,目前我得到了这个:

The Lord of the Rings
<ul>
    <li>Chapter 1</li>
    <li>Chapter 2</li>
    <li>Chapter 3</li>
    <li>Chapter N</li>
</ul>
<br><br>
Harry Potter
<ul>
    <li>Chapter 1</li>
    <li>Chapter 2</li>
    <li>Chapter 3</li>
    <li>Chapter N</li>
</ul>

更多详情:

  • 我正在使用PHP。
  • 唯一的参考我必须知道删除的链接是de#symbol。
  • 有些链接有新行。

示例:

<a href="http://example.com">
    new line</a>
or
<a href="http://example.com">new
    line</a>

4 个答案:

答案 0 :(得分:5)

您应该避免使用正则表达式,而应使用DOMDocumentDOMXPath

<?php
$dom = new DOMDocument();

$dom->loadHtml('
<a href="http://example.com/books/1">The Lord of the Rings</a>
<ul>
    <li><a   href="http://example.com/books/1#c1" >Chapter 1</a></li>
    <li><a name="name before href" href="http://example.com/books/1#c2">Chapter 2</a></li>
    <li><a href="http://example.com/books/1#c3" name="name after href">Chapter 3</a></li>
    <li><a href="http://example.com/books/1#cN" target="_blank">Chapter N</a></li>
</ul>
<br><br>
<a href="http://example.com/books/1">Harry Potter</a>
<ul>
    <li><a href="http://example.com/books/2#c1" target="_self">Chapter 1</a></li>
    <li><a href="http://example.com/books/2#c2" name="some have name" title="some others have title" >Chapter 2</a></li>
    <li><a href="http://example.com/books/2#c3">Chapter 3</a></li>
    <li><a href="http://example.com/books/2#cN"  >Chapter N</a></li>
</ul>
', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

$xpath = new DOMXPath($dom);

foreach ($xpath->query("//a") as $link) {
    $href = $link->getAttribute('href');

    // link has a # in it, so replace with the links title
    if (strpos($href, '#') !== false) {
        $link->parentNode->nodeValue = $link->nodeValue;
    }
}

echo $dom->saveHTML();

https://3v4l.org/8FQYb

<强>结果:

<a href="http://example.com/books/1">The Lord of the Rings<ul>
    <li>Chapter 1</li>
    <li>Chapter 2</li>
    <li>Chapter 3</li>
    <li>Chapter N</li>
</ul><br><br><a href="http://example.com/books/1">Harry Potter</a><ul>
    <li>Chapter 1</li>
    <li>Chapter 2</li>
    <li>Chapter 3</li>
    <li>Chapter N</li>
</ul></a>

答案 1 :(得分:2)

此正则表达式语句与您提供的示例相匹配。它会在网址中的#where中检测到这些网址。然后,您可以编写替换语句并将它们从捕获组\ 1

中交换掉所有文本
<a(?:\s+name=".*?")?\s+href=.*?#.*?>(.*?)<\/a>

Regex in action

答案 2 :(得分:0)

在解析HTML并选择所有HTML链接后,您可以使用foreach循环和str_replace,条件是字符串包含井号/井号符号。

<?php
//Save HTML code as an object using DOMDocument ($links) for parsing
foreach($links as $line) {
    if (str_pos($line, '#')) {
        str_replace($line, '', $links);
    }
}
?>

这将用带空白行的井号/井号符号替换每一行,数据库将对此进行处理。

答案 3 :(得分:0)

使用以下模式匹配文本中的<a href=...></a>,并将匹配的文本替换为空字符串。

(?<=<li>)<a.+?>|</a>(?=</li>)

这是为了删除不需要的字符串,而不是用想要的替换整个文本。