使用 preg_match 可以有相同的模式并有不同的替换吗?
With preg_match it's possible to have the same pattern and have different replacements?
我创造了这个模式
$pattern = "/<a href='(?<href>.+?)'>(?<name>.+?)<\/a>/i";
我有这个例子,
$string = "<a href='https://www.php.net/'>https://www.php.net/</a>
<a href='https://whosebug.com/'>https://whosebug.com/</a>
<a href='https://www.google.com/'>https://www.google.com/</a>";
使用它,我可以找到匹配项并提取 href 和名称。
preg_match_all($pattern, $string, $matches);
Array
(
[0] => Array
(
[0] => https://www.php.net/
[1] => https://whosebug.com/
[2] => https://www.google.com/
)
[href] => Array
(
[0] => https://www.php.net/
[1] => https://whosebug.com/
[2] => https://www.google.com/
)
[1] => Array
(
[0] => https://www.php.net/
[1] => https://whosebug.com/
[2] => https://www.google.com/
)
[name] => Array
(
[0] => https://www.php.net/
[1] => https://whosebug.com/
[2] => https://www.google.com/
)
[2] => Array
(
[0] => https://www.php.net/
[1] => https://whosebug.com/
[2] => https://www.google.com/
)
)
问题是当我使用 preg_replace 时,由于模式相同,它会为所有 URL 更改相同的信息,我只需要更改名称并保留其余信息相应。
正在使用,
if(preg_match_all($pattern, $string, $matches))
{
$string = preg_replace($pattern, "<a href=''>Name</a>", $string);
}
我可以从组中获取结果,并保留 href 的第一部分。但如果我尝试更改名称,所有结果都是一样的。
如果我尝试使用 "str_replace",我可能会得到不同的结果,但这给了我两个问题。一个是如果我尝试替换名称,我也会更改 href,如果我有类似 URL 和 "more slashes" 它将更改匹配部分,并保留其余信息。
在数据库中,我有 URL 的列表,其中有一列有名称,如果字符串与 table 中的任何行匹配,我需要相应地更改名称并保留 href。
有什么帮助吗?
谢谢。
亲切的问候!
我假设您从数据库中检索格式如下的行:
$rows = [
['href' => 'https://www.php.net/', 'name' => 'PHP.net'],
['href' => 'https://whosebug.com/', 'name' => 'Stack Overflow'],
['href' => 'https://www.google.com/', 'name' => 'Google']
];
从那里,您可以首先使用循环或 array_reduce
:
创建一个 href -> 名称映射
$rows_by_href = array_reduce($rows, function ($rows_by_href, $row) {
$rows_by_href[$row['href']] = $row['name'];
return $rows_by_href;
}, []);
然后您可以使用 preg_replace_callback
将每个匹配项替换为其关联名称(如果存在):
$result = preg_replace_callback($pattern, function ($matches) use ($rows_by_href) {
return "<a href='" . $matches['href'] . "'>"
. ($rows_by_href[$matches['href']] ?? $matches['name'])
. "</a>";
}, $string);
echo $result;
请注意,这假定 $string
中的 URL (href) 的格式与来自您的数据库的格式完全相同。否则,您可以 rtrim
尾部斜杠或事先做任何您需要的事情。
另请注意,如果可以避免,使用正则表达式解析 HTML 通常不是一个好主意。 DOM 解析器更合适,除非您必须解析来自评论或论坛 post 或不受您控制的内容的字符串。
我创造了这个模式
$pattern = "/<a href='(?<href>.+?)'>(?<name>.+?)<\/a>/i";
我有这个例子,
$string = "<a href='https://www.php.net/'>https://www.php.net/</a>
<a href='https://whosebug.com/'>https://whosebug.com/</a>
<a href='https://www.google.com/'>https://www.google.com/</a>";
使用它,我可以找到匹配项并提取 href 和名称。
preg_match_all($pattern, $string, $matches);
Array
(
[0] => Array
(
[0] => https://www.php.net/
[1] => https://whosebug.com/
[2] => https://www.google.com/
)
[href] => Array
(
[0] => https://www.php.net/
[1] => https://whosebug.com/
[2] => https://www.google.com/
)
[1] => Array
(
[0] => https://www.php.net/
[1] => https://whosebug.com/
[2] => https://www.google.com/
)
[name] => Array
(
[0] => https://www.php.net/
[1] => https://whosebug.com/
[2] => https://www.google.com/
)
[2] => Array
(
[0] => https://www.php.net/
[1] => https://whosebug.com/
[2] => https://www.google.com/
)
)
问题是当我使用 preg_replace 时,由于模式相同,它会为所有 URL 更改相同的信息,我只需要更改名称并保留其余信息相应。
正在使用,
if(preg_match_all($pattern, $string, $matches))
{
$string = preg_replace($pattern, "<a href=''>Name</a>", $string);
}
我可以从组中获取结果,并保留 href 的第一部分。但如果我尝试更改名称,所有结果都是一样的。
如果我尝试使用 "str_replace",我可能会得到不同的结果,但这给了我两个问题。一个是如果我尝试替换名称,我也会更改 href,如果我有类似 URL 和 "more slashes" 它将更改匹配部分,并保留其余信息。
在数据库中,我有 URL 的列表,其中有一列有名称,如果字符串与 table 中的任何行匹配,我需要相应地更改名称并保留 href。
有什么帮助吗?
谢谢。
亲切的问候!
我假设您从数据库中检索格式如下的行:
$rows = [
['href' => 'https://www.php.net/', 'name' => 'PHP.net'],
['href' => 'https://whosebug.com/', 'name' => 'Stack Overflow'],
['href' => 'https://www.google.com/', 'name' => 'Google']
];
从那里,您可以首先使用循环或 array_reduce
:
$rows_by_href = array_reduce($rows, function ($rows_by_href, $row) {
$rows_by_href[$row['href']] = $row['name'];
return $rows_by_href;
}, []);
然后您可以使用 preg_replace_callback
将每个匹配项替换为其关联名称(如果存在):
$result = preg_replace_callback($pattern, function ($matches) use ($rows_by_href) {
return "<a href='" . $matches['href'] . "'>"
. ($rows_by_href[$matches['href']] ?? $matches['name'])
. "</a>";
}, $string);
echo $result;
请注意,这假定 $string
中的 URL (href) 的格式与来自您的数据库的格式完全相同。否则,您可以 rtrim
尾部斜杠或事先做任何您需要的事情。
另请注意,如果可以避免,使用正则表达式解析 HTML 通常不是一个好主意。 DOM 解析器更合适,除非您必须解析来自评论或论坛 post 或不受您控制的内容的字符串。