我正面临着URL的问题,我希望能够转换可能包含任何内容的标题并将它们删除所有特殊字符,这样它们只有字母和数字,当然我想用连字符替换空格。
如何做到这一点?我听说过很多关于使用正则表达式(正则表达式)...
答案 0 :(得分:588)
容易腻:
function clean($string) {
$string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.
return preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.
}
用法:
echo clean('a|"bc!@£de^&$f g');
将输出:abcdef-g
修改
嘿,只是一个简单的问题,我怎样才能防止多个连字符彼此相邻?并将它们替换为1?
function clean($string) {
$string = str_replace(' ', '-', $string); // Replaces all spaces with hyphens.
$string = preg_replace('/[^A-Za-z0-9\-]/', '', $string); // Removes special chars.
return preg_replace('/-+/', '-', $string); // Replaces multiple hyphens with single one.
}
答案 1 :(得分:93)
下面的解决方案有一个“SEO友好”版本:
function hyphenize($string) {
$dict = array(
"I'm" => "I am",
"thier" => "their",
// Add your own replacements here
);
return strtolower(
preg_replace(
array( '#[\\s-]+#', '#[^A-Za-z0-9\. -]+#' ),
array( '-', '' ),
// the full cleanString() can be downloaded from http://www.unexpectedit.com/php/php-clean-string-of-utf8-chars-convert-to-similar-ascii-char
cleanString(
str_replace( // preg_replace can be used to support more complicated replacements
array_keys($dict),
array_values($dict),
urldecode($string)
)
)
)
);
}
function cleanString($text) {
$utf8 = array(
'/[áàâãªä]/u' => 'a',
'/[ÁÀÂÃÄ]/u' => 'A',
'/[ÍÌÎÏ]/u' => 'I',
'/[íìîï]/u' => 'i',
'/[éèêë]/u' => 'e',
'/[ÉÈÊË]/u' => 'E',
'/[óòôõºö]/u' => 'o',
'/[ÓÒÔÕÖ]/u' => 'O',
'/[úùûü]/u' => 'u',
'/[ÚÙÛÜ]/u' => 'U',
'/ç/' => 'c',
'/Ç/' => 'C',
'/ñ/' => 'n',
'/Ñ/' => 'N',
'/–/' => '-', // UTF-8 hyphen to "normal" hyphen
'/[’‘‹›‚]/u' => ' ', // Literally a single quote
'/[“”«»„]/u' => ' ', // Double quote
'/ /' => ' ', // nonbreaking space (equiv. to 0x160)
);
return preg_replace(array_keys($utf8), array_values($utf8), $text);
}
上述功能的基本原理(我发现方式低效 - 下面的那个更好)是一个不应命名的服务显然运行拼写检查和关键字识别URL。
在客户的偏执狂失去了很长一段时间之后,我发现他们不想象事情 - 他们的SEO专家[我绝对不是一个]报道说,转换“Viaggi经济Perù“到viaggi-economy-peru
”表现得比viaggi-economy-per
更好(之前的“清理”删除了UTF8字符; Bogotà成为 bogot , Medellìn成为 medelln 等等。
还有一些常见的拼写错误似乎影响了结果,唯一对我有意义的解释是我们的URL被解压缩,单词被挑出来,用来驱动上帝知道排序算法。这些算法显然已经用UTF8清理过的字符串,因此“Perù”变成了“秘鲁”而不是“Per”。 “Per”并不匹配,并把它放在脖子上。
为了保持UTF8字符并替换一些拼写错误,下面更快的函数变成了上面更准确的(?)函数。当然,$dict
需要手工定制。
一种简单的方法:
// Remove all characters except A-Z, a-z, 0-9, dots, hyphens and spaces
// Note that the hyphen must go last not to be confused with a range (A-Z)
// and the dot, being special, is escaped with \
$str = preg_replace('/[^A-Za-z0-9\. -]/', '', $str);
// Replace sequences of spaces with hyphen
$str = preg_replace('/ */', '-', $str);
// The above means "a space, followed by a space repeated zero or more times"
// (should be equivalent to / +/)
// You may also want to try this alternative:
$str = preg_replace('/\\s+/', '-', $str);
// where \s+ means "zero or more whitespaces" (a space is not necessarily the
// same as a whitespace) just to be sure and include everything
请注意,您可能必须先urldecode()
这个网址,因为%20和+都是空格 - 我的意思是,如果你有“从不%20永远不会给你,而不是 Never20gonna20give20you20up 。你可能不需要它,但我想我会提到这种可能性。
所以完成的函数和测试用例:
function hyphenize($string) {
return
## strtolower(
preg_replace(
array('#[\\s-]+#', '#[^A-Za-z0-9\. -]+#'),
array('-', ''),
## cleanString(
urldecode($string)
## )
)
## )
;
}
print implode("\n", array_map(
function($s) {
return $s . ' becomes ' . hyphenize($s);
},
array(
'Never%20gonna%20give%20you%20up',
"I'm not the man I was",
"'Légeresse', dit sa majesté",
)));
Never%20gonna%20give%20you%20up becomes never-gonna-give-you-up
I'm not the man I was becomes im-not-the-man-I-was
'Légeresse', dit sa majesté becomes legeresse-dit-sa-majeste
为了处理UTF-8,我使用了在线发现的cleanString
实现(链接破了以后,但是一个带有所有不太深奥的UTF8字符的精简副本在答案的开头;它也很容易如果需要,可以为其添加更多字符,将UTF8字符转换为普通字符,从而尽可能保留单词“look”。它可以简化并包含在函数内部以提高性能。
上面的函数也实现了转换为小写 - 但这是一种品味。这样做的代码已经被注释掉了。
答案 2 :(得分:34)
在这里,看看这个功能:
function seo_friendly_url($string){
$string = str_replace(array('[\', \']'), '', $string);
$string = preg_replace('/\[.*\]/U', '', $string);
$string = preg_replace('/&(amp;)?#?[a-z0-9]+;/i', '-', $string);
$string = htmlentities($string, ENT_COMPAT, 'utf-8');
$string = preg_replace('/&([a-z])(acute|uml|circ|grave|ring|cedil|slash|tilde|caron|lig|quot|rsquo);/i', '\\1', $string );
$string = preg_replace(array('/[^a-z0-9]/i', '/[-]+/') , '-', $string);
return strtolower(trim($string, '-'));
}