我想将一个字符串转换成URL,需要实现以下功能:
- 只保留字母数字字符、空格和短横线。
- 将空格转换为短横线。
例如:
This, is the URL!
必须返回
this-is-the-url
我想将一个字符串转换成URL,需要实现以下功能:
例如:
This, is the URL!
必须返回
this-is-the-url
function slug($z){
$z = strtolower($z);
$z = preg_replace('/[^a-z0-9 -]+/', '', $z);
$z = str_replace(' ', '-', $z);
return trim($z, '-');
}
首先去除不需要的字符
$new_string = preg_replace("/[^a-zA-Z0-9\s]/", "", $string);
然后将空格改为下划线
$url = preg_replace('/\s/', '-', $new_string);
$new_url = urlencode($url);
_
是下划线,-
是连字符。在这样的字符串上使用 urlencode
不会改变任何东西。你还忘记了第一个正则表达式中的连字符,\s
不等同于空格字符。 - SilentGhostOP并没有明确描述slug的所有属性,但这是我从意图中得出的。
我的解释与此帖子所述的完美、有效、简洁的slug一致:https://wordpress.stackexchange.com/questions/149191/slug-formatting-acceptable-characters#:~:text=However%2C%20we%20can%20summarise%20the,or%20end%20with%20a%20hyphen。
我发现早期发布的答案都无法始终如一地实现这一点(我甚至没有将问题范围扩展到包括多字节字符)。
我推荐以下一行命令,它不需要声明仅用一次的变量:
return trim(preg_replace('/[^a-z0-9]+/', '-', strtolower($string)), '-');
我还准备了一份演示,突出展示其他答案中我认为存在的不准确之处。(演示)
'This, is - - the URL!' input
'this-is-the-url' expected
'this-is-----the-url' SilentGhost
'this-is-the-url' mario
'This-is---the-URL' Rooneyl
'This-is-the-URL' AbhishekGoel
'This, is - - the URL!' HelloHack
'This, is - - the URL!' DenisMatafonov
'This,-is-----the-URL!' AdeelRazaAzeemi
'this-is-the-url' mickmackusa
---
'Mork & Mindy' input
'mork-mindy' expected
'mork--mindy' SilentGhost
'mork-mindy' mario
'Mork--Mindy' Rooneyl
'Mork-Mindy' AbhishekGoel
'Mork & Mindy' HelloHack
'Mork & Mindy' DenisMatafonov
'Mork-&-Mindy' AdeelRazaAzeemi
'mork-mindy' mickmackusa
---
'What the_underscore ?!?' input
'what-the-underscore' expected
'what-theunderscore' SilentGhost
'what-the_underscore' mario
'What-theunderscore-' Rooneyl
'What-theunderscore-' AbhishekGoel
'What the_underscore ?!?' HelloHack
'What the_underscore ?!?' DenisMatafonov
'What-the_underscore-?!?' AdeelRazaAzeemi
'what-the-underscore' mickmackusa
试试这个
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.
}
使用方法:
echo clean('a|"bc!@£de^&$f g');
将输出:abcdef-g
使用intl转换器是一个不错的选择,因为它可以轻松地处理复杂情况,并且只需要一组规则。我添加了自定义规则来说明它有多灵活,以及如何保留最大限度的有意义信息。随时可以删除它们并添加自己的规则。
$strings = [
'This, is - - the URL!',
'Holmes & Yoyo',
'L’Œil de démon',
'How to win 1000€?',
'€, $ & other currency symbols',
'Und die Katze fraß alle mäuse.',
'Белите рози на София',
'പോണ്ടിച്ചേരി സൂര്യനു കീഴിൽ',
];
$rules = <<<'RULES'
# Transliteration
:: Any-Latin ; :: Latin-Ascii ;
# examples of custom replacements
'&' > ' and ' ;
[^0-9][01]? { € > ' euro' ; € > ' euros' ;
[^0-9][01]? { '$' > ' dollar' ; '$' > ' dollars' ;
:: Null ;
# slugify
[^[:alnum:]&[:ascii:]]+ > '-' ;
:: Lower ;
# trim
[$] { '-' > &Remove() ;
'-' } [$] > &Remove() ;
RULES;
$tsl = Transliterator::createFromRules($rules, Transliterator::FORWARD);
$results = array_map(fn($s) => $tsl->transliterate($s), $strings);
print_r($results);
不幸的是,PHP手册完全没有关于ICU转换的内容,但你可以在这里找到相关信息。
这将在Unix shell中完成(我刚在我的MacOS上尝试过):
$ tr -cs A-Za-z '-' < infile.txt > outfile.txt
我从More Shell, Less Egg的博客文章中得到了这个想法。
所有之前的答案都涉及到URL,但是如果有人需要对登录字符串进行清理(例如),并将其保留为文本,则可以使用以下方法:
function sanitizeText($str) {
$withSpecCharacters = htmlspecialchars($str);
$splitted_str = str_split($str);
$result = '';
foreach ($splitted_str as $letter){
if (strpos($withSpecCharacters, $letter) !== false) {
$result .= $letter;
}
}
return $result;
}
echo sanitizeText('ОРРииыфвсси ajvnsakjvnHB "&nvsp;\n" <script>alert()</script>');
//ОРРииыфвсси ajvnsakjvnHB &nvsp;\n scriptalert()/script
//No injections possible, all info at max keeped
function isolate($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
以下将把空格替换为破折号。
$str = str_replace(' ', '-', $str);
接下来的语句将删除除了字母数字和破折号以外的所有字符。(因为在之前的步骤中我们已经用破折号替换了空格。)
// Char representation 0 - 9 A- Z a- z -
$str = preg_replace('/[^\x30-\x39\x41-\x5A\x61-\x7A\x2D]/', '', $str);
这相当于什么?
$str = preg_replace('/[^0-9A-Za-z-]+/', '', $str);
提示:要从字符串中删除所有特殊字符,请使用
$str = preg_replace('/[^\x20-\x7E]/', '', $str);
\x20 是空格的十六进制表示,它是 ASCII 字符的开始,而 \x7E 是波浪号。根据维基百科 https://en.wikipedia.org/wiki/ASCII#Printable_characters 的说法。
请注意:查看 20-7E 的间隔的十六进制列
可打印字符 20hex 到 7Ehex 的代码,称为可打印字符,代表字母、数字、标点符号和一些杂项符号。总共有 95 个可打印字符。