取一个字符串,如。
在C#中。如何在逗号分隔的字符串列表中添加 "引号"?
并将其转换为
in-c-how-do-i-add-quotes-around-string-in-a-comma-delimited-list-of-strings。
要求:每一个字用破折号隔开,去掉所有标点符号。
ToSeoFriendly("hello world hello world", 14)
返回 "hello-world"
另外说一句,是否应该有一个最小长度?
这是我在C#中的解决方案
private string ToSeoFriendly(string title, int maxLength) {
var match = Regex.Match(title.ToLower(), "[\\w]+");
StringBuilder result = new StringBuilder("");
bool maxLengthHit = false;
while (match.Success && !maxLengthHit) {
if (result.Length + match.Value.Length <= maxLength) {
result.Append(match.Value + "-");
} else {
maxLengthHit = true;
// Handle a situation where there is only one word and it is greater than the max length.
if (result.Length == 0) result.Append(match.Value.Substring(0, maxLength));
}
match = match.NextMatch();
}
// Remove trailing '-'
if (result[result.Length - 1] == '-') result.Remove(result.Length - 1, 1);
return result.ToString();
}
我会按照这些步骤进行。
preg_replace()
函数调用已经防止了多个连字符)所以,所有这些都集中在一个函数中(PHP)。
function generateUrlSlug($string, $maxlen=0)
{
$string = trim(preg_replace('/[^a-z0-9]+/', '-', strtolower($string)), '-');
if ($maxlen && strlen($string) > $maxlen) {
$string = substr($string, 0, $maxlen);
$pos = strrpos($string, '-');
if ($pos > 0) {
$string = substr($string, 0, $pos);
}
}
return $string;
}
C#
public string toFriendly(string subject)
{
subject = subject.Trim().ToLower();
subject = Regex.Replace(subject, @"\s+", "-");
subject = Regex.Replace(subject, @"[^A-Za-z0-9_-]", "");
return subject;
}
这里有一个php的解决方案。
function make_uri($input, $max_length) {
if (function_exists('iconv')) {
$input = @iconv('UTF-8', 'ASCII//TRANSLIT', $input);
}
$lower = strtolower($input);
$without_special = preg_replace_all('/[^a-z0-9 ]/', '', $input);
$tokens = preg_split('/ +/', $without_special);
$result = '';
for ($tokens as $token) {
if (strlen($result.'-'.$token) > $max_length+1) {
break;
}
$result .= '-'.$token;
}
return substr($result, 1);
}
用途:
echo make_uri('In C#: How do I add "Quotes" around string in a ...', 500);
除非你需要uris是可打字的,否则它们不需要太小。 但你应该指定一个最大值,这样urls就能很好地与代理服务器等配合使用。
一个更好的版本。
function Slugify($string)
{
return strtolower(trim(preg_replace(array('~[^0-9a-z]~i', '~-+~'), '-', $string), '-'));
}
Perl中的解决方案:
my $input = 'In C#: How do I add "Quotes" around string in a comma delimited list of strings?';
my $length = 20;
$input =~ s/[^a-z0-9]+/-/gi;
$input =~ s/^(.{1,$length}).*/\L$1/;
print "$input\n";
done.
在 shell 中的解决方案。
echo 'In C#: How do I add "Quotes" around string in a comma delimited list of strings?' | \
tr A-Z a-z | \
sed 's/[^a-z0-9]\+/-/g;s/^\(.\{1,20\}\).*/\1/'
这和Stack Overflow生成slugs的方式很接近。
public static string GenerateSlug(string title)
{
string slug = title.ToLower();
if (slug.Length > 81)
slug = slug.Substring(0, 81);
slug = Regex.Replace(slug, @"[^a-z0-9\-_\./\\ ]+", "");
slug = Regex.Replace(slug, @"[^a-z0-9]+", "-");
if (slug[slug.Length - 1] == '-')
slug = slug.Remove(slug.Length - 1, 1);
return slug;
}
至少在PHP中一个稍微干净的方法是这样的。
function CleanForUrl($urlPart, $maxLength = null) {
$url = strtolower(preg_replace(array('/[^a-z0-9\- ]/i', '/[ \-]+/'), array('', '-'), trim($urlPart)));
if ($maxLength) $url = substr($url, 0, $maxLength);
return $url;
}
不如这样做 trim()
在开始时,这样以后需要处理的事情就少了,而全部的替换工作都是在 preg_replace()
.
Thxs to cg想出了大部分的办法。什么是最好的方法来清理一个字符串以放置在URL中,比如SO的问题名称?
又是一个季节,又是一个选择Ruby的理由 :)
def seo_friendly(str)
str.strip.downcase.gsub /\W+/, '-'
end
就这些了。
在python中,(如果安装了django,即使你使用的是其他框架。
from django.template.defaultfilters import slugify
slugify("In C#: How do I add "Quotes" around string in a comma delimited list of strings?")
要做到这一点,我们需要。
我想用一个函数来生成整个字符串,并有一个可能的最大长度的输入,这就是结果。
public static class StringHelper
{
/// <summary>
/// Creates a URL And SEO friendly slug
/// </summary>
/// <param name="text">Text to slugify</param>
/// <param name="maxLength">Max length of slug</param>
/// <returns>URL and SEO friendly string</returns>
public static string UrlFriendly(string text, int maxLength = 0)
{
// Return empty value if text is null
if (text == null) return "";
var normalizedString = text
// Make lowercase
.ToLowerInvariant()
// Normalize the text
.Normalize(NormalizationForm.FormD);
var stringBuilder = new StringBuilder();
var stringLength = normalizedString.Length;
var prevdash = false;
var trueLength = 0;
char c;
for (int i = 0; i < stringLength; i++)
{
c = normalizedString[i];
switch (CharUnicodeInfo.GetUnicodeCategory(c))
{
// Check if the character is a letter or a digit if the character is a
// international character remap it to an ascii valid character
case UnicodeCategory.LowercaseLetter:
case UnicodeCategory.UppercaseLetter:
case UnicodeCategory.DecimalDigitNumber:
if (c < 128)
stringBuilder.Append(c);
else
stringBuilder.Append(ConstHelper.RemapInternationalCharToAscii(c));
prevdash = false;
trueLength = stringBuilder.Length;
break;
// Check if the character is to be replaced by a hyphen but only if the last character wasn't
case UnicodeCategory.SpaceSeparator:
case UnicodeCategory.ConnectorPunctuation:
case UnicodeCategory.DashPunctuation:
case UnicodeCategory.OtherPunctuation:
case UnicodeCategory.MathSymbol:
if (!prevdash)
{
stringBuilder.Append('-');
prevdash = true;
trueLength = stringBuilder.Length;
}
break;
}
// If we are at max length, stop parsing
if (maxLength > 0 && trueLength >= maxLength)
break;
}
// Trim excess hyphens
var result = stringBuilder.ToString().Trim('-');
// Remove any excess character to meet maxlength criteria
return maxLength <= 0 || result.Length <= maxLength ? result : result.Substring(0, maxLength);
}
}
这个帮助程序用于将一些国际字符重新转换为可读字符。
public static class ConstHelper
{
/// <summary>
/// Remaps international characters to ascii compatible ones
/// based of: https://meta.stackexchange.com/questions/7435/non-us-ascii-characters-dropped-from-full-profile-url/7696#7696
/// </summary>
/// <param name="c">Charcter to remap</param>
/// <returns>Remapped character</returns>
public static string RemapInternationalCharToAscii(char c)
{
string s = c.ToString().ToLowerInvariant();
if ("àåáâäãåą".Contains(s))
{
return "a";
}
else if ("èéêëę".Contains(s))
{
return "e";
}
else if ("ìíîïı".Contains(s))
{
return "i";
}
else if ("òóôõöøőð".Contains(s))
{
return "o";
}
else if ("ùúûüŭů".Contains(s))
{
return "u";
}
else if ("çćčĉ".Contains(s))
{
return "c";
}
else if ("żźž".Contains(s))
{
return "z";
}
else if ("śşšŝ".Contains(s))
{
return "s";
}
else if ("ñń".Contains(s))
{
return "n";
}
else if ("ýÿ".Contains(s))
{
return "y";
}
else if ("ğĝ".Contains(s))
{
return "g";
}
else if (c == 'ř')
{
return "r";
}
else if (c == 'ł')
{
return "l";
}
else if (c == 'đ')
{
return "d";
}
else if (c == 'ß')
{
return "ss";
}
else if (c == 'þ')
{
return "th";
}
else if (c == 'ĥ')
{
return "h";
}
else if (c == 'ĵ')
{
return "j";
}
else
{
return "";
}
}
}
这个函数的工作原理是这样的
const string text = "ICH MUß EINIGE CRÈME BRÛLÉE HABEN";
Console.WriteLine(StringHelper.URLFriendly(text));
// Output:
// ich-muss-einige-creme-brulee-haben
这个问题已经回答过很多次了 此处 但没有一个是优化过的,你可以找到整个源码。这里的github 更多内容你可以从 Johan Boström的博客. 更多的是兼容.NET 4.5+和.NET Core。