我在这里暴露了我的正则表达式技能的尴尬无知, 但是:我目前有一个网站, 其中大量文章的URL被写成"article_name", 而较新的文章则被写成"article-name"。
我想将它们全部改为使用破折号, 那么是否有正则表达式可以用来将旧的URL重写为它们的新版本?
提前感谢您!
我在这里暴露了我的正则表达式技能的尴尬无知, 但是:我目前有一个网站, 其中大量文章的URL被写成"article_name", 而较新的文章则被写成"article-name"。
我想将它们全部改为使用破折号, 那么是否有正则表达式可以用来将旧的URL重写为它们的新版本?
提前感谢您!
首先,您必须使现有的URL保持一致性。基本上,您必须将所有现有名称规范化为始终使用破折号。好的,您已经做到了这一点。
我们从以下假设开始:
URL大致形式如下:
http://example.com/articles/what-ever/really-doesnt_matter/faulty_article_name
只有在/articles
下的URL才需要重写,只有/faulty_article_name
部分需要进行消毒。
对于Apache:
RewriteEngine On
RewriteRule ^(/?articles/.*/[^/]*?)_([^/]*?_[^/]*)$ $1-$2 [N]
RewriteRule ^(/?articles/.*/[^/]*?)_([^/_]*)$ $1-$2 [R=301]
这通常是受 GApple 的回答启发而来。
第一个 /?
确保此代码将在虚拟主机配置和 .htaccess
文件上运行。后者不需要前导斜杠。
然后我添加了 articles/
部分,以确保规则仅适用于 /articles
中的 URL。
然后,在 URL 中有至少两个下划线时,我们通过规则循环进行。当我们最终只剩下一个下划线时,第二条规则就会生效,用连字符替换它,并进行永久重定向。
呼~
试试这个:
RewriteRule ^([^_]*)_([^_]*_.*) $1-$2 [N]
RewriteRule ^([^_]*)_([^_]*)$ /$1-$2 [L,R=301]
第一条规则会逐个替换下划线,直到只剩一个或没有下划线。最后一条规则将替换最后一个下划线并执行外部重定向。RewriteRule ^([^_]*)_([^_]*_.*).html $1-$2.html [N]
RewriteRule ^([^_]*)_([^_]*).html$ /$1-$2.html [L,R=301]
它只重写HTML文件。 - dpavlinhttp://example.com/a/a_b_c/
。 - pcworldDPI
(Discard Path Info)标志(请注意,尾随斜杠也会创建额外的路径段)。 (在替换项前加上斜杠,以便将其重写为URL路径,而不是文件系统路径,在某些情况下也可能有所帮助。) - MrWhite一个可能不同的思路:
我假设你的“旧格式”和“新格式”将在不同的目录中,如果它们不是,你可能需要考虑让新格式有一个不同的目录名称。
例如:
http://site.com/articles/2008/12/31/new_years_celebration
http://site.com/article/2008/12/31/new_years_celebration
这种情况下,您可以使用mod_rewrite来检测“旧目录”中的任何内容,并将其重定向到“redirector.php
”。
尽管在重新考虑后,您的mod_rewrite可能会寻找像这样的东西:
RedirectRule /articles/(.*_.*) /redirector.php?article=$1
匹配任何带有_
的内容并将其发送到重定向器。
在redirector.php中,您可以获取$_SERVER['REQUEST_URI']
,并使用preg_replace等工具甚至数据库查询来查找正确的URL以将其重定向 - 以及研究旧URL的点击次数。
mod_rewrite如何知道实际的URL应该是什么?您可以将所有文章重写为使用下划线或破折号,但是mod_rewrite
无法确定新位置是否存在。
例如,
/I_Like_Bees 存储为 /path/i_like_bees /I-like-flowers 存储为 /path/i-like-flowers
您想要i-like-bees
重写为i_like_bees
。
i_like_bees
i-like-flowers
如果您始终一致地存储所有文章,则可以轻松制作重写规则。相反,您可能需要编写脚本来检查目录是否存在,并执行301重定向到正确的位置。
以防其他人遇到和我一样的情况,我只想将此规则应用于目录/episodes/listen/下的剧集标题。
旧URL: https://example.com/episodes/listen/2_episode_1/index.php
所需URL: https://example.com/episodes/listen/2-episode-1/index.php
RewriteEngine On
RewriteRule ^(/?episodes/listen/[^_]*)_([^_]*_.*)$ $1-$2 [N,DPI]
RewriteRule ^(/?episodes/listen/[^_]*)_([^_]*)$ [L,R=301]
这里有一个方法:http://yoast.com/apache-rewrite-dash-underscore/
基本上,它将URL分成下划线两侧的标记,并重新编写标记,用下划线替换。问题是它一次只能替换一个下划线;它将重定向到更接近但不完全正确的URL,然后再次重定向到更接近但可能仍然不正确的URL...
建议通过具有逐步更多下划线和标记的几个重写条件和规则来修复多个重定向,但这将需要与您最长标题中的下划线数量相同的条件和规则。
但请确保添加任何限定词,因为该规则可能会替换您不想更改的路径(例如,图像文件)。