PHP模式搜索和替换


PHP pattern search and replace

我在数据库中有一堆rawr内容。

某些包含字符串http://www.example.com/subfolder/name.pdf/subfolder/name.pdf

我需要一个模式替换这些,把它们变成/wp-content/uploads/old/subfolder/name.pdf,可以有很多层次的子文件夹!/subfolder1/subfolder2/subfolder3/file.pdf

我使用的查找模式是
/http[^'s]+pdf/
/href="'/[^'s]+pdf/

但是如何用另一个模式替换这个模式呢?(上面的例子^)

我有

search for /http:'/'/www.example.com(.*).pdf"/
replace with /wp-content/uploads/old$1.pdf"
search for /href="'/pdf(.*)'.pdf">/

直到在一个表格单元格中有超过1个PDF链接

例子

<a href="/pdf/subdir/name.pdf">clickhere</a><a href="/pdf/subdir/name.pdf">2nd PDF</a>

直到在一个表格单元格中有超过1个PDF链接

默认情况下,regex引擎是贪婪的,它尽可能地消耗匹配。为了扭转这种行为,你可以使用懒惰量词,正如这篇文章所解释的:贪婪、不情愿、所有格量词。因此,您必须在量词之后添加额外的?,以尝试使用尽可能少的量词进行匹配。要使贪心构造变懒,可以使用[^'s]+? .

一些包含字符串http://www.example.com/subfolder/name.pdfor /subfolder/name.pdf

但是如何用另一个模式替换这个模式呢?

可以看到," http://www.example.com "是可选的。您可以使用(?:group)?量词使模式的一部分成为可选的。

带有可选组的模式:

(?:http://www'.example'.com)?/('S+?)'.pdf
    不要忘记转义点,因为它们在正则表达式中有特殊的含义。
  • 注意,我使用'S(大写"S")而不是[^'s](它们都完全相同)。


还有一件事,您可以考虑在您的模式中添加一些边界。我建议使用(?<!'w)(前面没有单词字符)和'b作为单词边界,以避免匹配作为另一个单词的一部分(正如我在您的问题中评论的那样)。

正则表达式:

(?<!'w)(?:http://www'.example'.com)?/('S+?)'.pdf'b

代码:

$re = "@(?<!''w)(?:http://www''.example''.com)?/(''S+?)''.pdf''b@i"; 
$str = "some containing string http://www.example.com/subfolder/name.pdf
        or /subfolder/name.pdf
        <a href='"/pdf/subdir/name.pdf'">clickhere</a>
        <a href='"/pdf/subdir/name.pdf'">2nd PDF</a>"; 
$subst = "/wp-content/uploads/old/$1.pdf"; 
$result = preg_replace($re, $subst, $str);

测试regex101

这里有一个沙盒示例:http://sandbox.onlinephpfunctions.com/code/cc47b98d16981b786cf2d573751b6a09a9725b90

$array = [
     "https://test.com/url/subfolder/subfolder/file.pdf",
     "https://test.com/url/subfolder1/subfolder/file.pdf",
     "/url/subfolder3/subfolder3/files.xml",
     "/url/subfolder/subfolder/file.pdf"
];
function setwpUrl($urls, $prepend) {
    for($i = 0; $i < count($urls); $i++) {
        preg_match_all("/(https?:'/'/[a-zA-Z0-9'.'-]+)?(.*)/", $urls[$i], $out);
        $urls[$i] = $prepend . $out[2][0];
    }
    return $urls;
}
$newUrls = setwpUrl($array, "/wp-content/uploads/old");
var_dump($newUrls);