以智能的方式在C#中移除所有有问题的字符

3
有没有任何 .Net 库可以智能地删除字符串中所有问题字符,只保留字母数字、连字符和下划线(或类似子集)?这是为了在 URL、文件名等中使用。
我正在寻找类似于 stringex 的东西,它可以执行以下操作:

一个简单的序言

"simple English".to_url => "simple-english"

"it's nothing at all".to_url => "its-nothing-at-all"

"rock & roll".to_url => "rock-and-roll"

让我们炫耀一下

"$12 worth of Ruby power".to_url => "12-dollars-worth-of-ruby-power"

"10% off if you act now".to_url => "10-percent-off-if-you-act-now"

你甚至不想相信Iconv可以完成以下部分

"kick it en Français".to_url => "kick-it-en-francais"

"rock it Español style".to_url => "rock-it-espanol-style"

"tell your readers 你好".to_url => "tell-your-readers-ni-hao"


BillW,我不是在寻找这个,我只是举了一个智能替换的例子,以防有人发布一个简单的正则表达式(这也是我已经在使用的解决方案)。特别是关于翻译部分,我并不太在意。 - pupeno
1
JPF,很抱歉没有理解你的主要意图;很高兴你得到了所需的东西。我很惊讶“stringex”库在其“ActsAsUrl”组件中甚至可以处理一个或两个非罗马(例如你的例子中的中文)字形转换成英语音素的情况! - BillW
9个回答

3
你可以尝试这个。
string str = phrase.ToLower();  //optional
str = str.Trim();
str = Regex.Replace(str, @"[^a-z0-9\s_]", ""); // invalid chars        
str = Regex.Replace(str, @"\s+", " ").Trim(); // convert multiple spaces into one space
str = str.Substring(0, str.Length <= 400 ? str.Length : 400).Trim(); // cut and trim it
str = Regex.Replace(str, @"\s", "-");

2
也许这里的问题可以帮助你。它提供了代码,说明Stackoverflow如何生成其URL(更具体地说,是如何将问题名称转换为漂亮的URL)。请参考此处链接,Jeff Atwood在其中展示了他们的代码。

1

从您的示例中,我找到的最接近的东西(尽管我认为它不会完全满足您的需求)是:

C#中我最喜欢的字符串扩展方法

还有:

ÜberUtils - Part 3 : Strings

由于这两个解决方案都无法完全满足您的要求(根据您问题中的示例),并且假设目标是使您的字符串“安全”,我赞成Hogan的建议,并使用Microsoft's Anti Cross Site Scripting Library,或者至少将其用作您自己创建的基础,可能派生自该库。

这里是一个链接到一个类的链接,该类构建了许多字符串扩展方法(就像前两个示例一样),但利用了Microsoft的AntiXSS库:

AntiXss 的扩展方法

当然,您可以始终将 AntiXSS 库中使用的算法(或类似算法)与常用于网站生成“slug”URL的算法相结合(就像 Stack Overflow 和许多博客平台一样)。

这是一个好的 C# slug 生成器示例:

改进的 C# Slug 生成器


0

由于您提出了要应用特定规则的需求,比如 $x => x-dollars,x% => x-percent,因此没有现成的库能够满足您的要求。几乎可以确定,您需要自己编写方法来实现这个功能。不过,这并不难。您可以使用字符串扩展方法,并使用一个或多个正则表达式进行替换,这样做可能是相当简洁明了的。

例如:

public static string ToUrl(this string text)
{
    return text.Trim().Regex.Replace(text, ..., ...);
}

0

我在我的博客中使用类似这样的东西。

public class Post
{

    public string Subject { get; set; }

    public string ResolveSubjectForUrl()
    {
        return Regex.Replace(Regex.Replace(this.Subject.ToLower(), "[^\\w]", "-"), "[-]{2,}", "-");
    }

}

0

我找不到任何像 Ruby 中那样的库来完成它,所以最终我自己编写了一个方法。如果有人感兴趣,这就是它:

/// <summary>
/// Turn a string into something that's URL and Google friendly.
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string ForUrl(this string str) {
  return str.ForUrl(true);
}
public static string ForUrl(this string str, bool MakeLowerCase) {
  // Go to lowercase.
  if (MakeLowerCase) {
    str = str.ToLower();
  }

  // Replace accented characters for the closest ones:
  char[] from = "ÂÃÄÀÁÅÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝàáâãäåçèéêëìíîïðñòóôõöøùúûüýÿ".ToCharArray();
  char[] to = "AAAAAACEEEEIIIIDNOOOOOOUUUUYaaaaaaceeeeiiiidnoooooouuuuyy".ToCharArray();
  for (int i = 0; i < from.Length; i++) {
    str = str.Replace(from[i], to[i]);
  }

  // Thorn http://en.wikipedia.org/wiki/%C3%9E
  str = str.Replace("Þ", "TH");
  str = str.Replace("þ", "th");

  // Eszett http://en.wikipedia.org/wiki/%C3%9F
  str = str.Replace("ß", "ss");

  // AE http://en.wikipedia.org/wiki/%C3%86
  str = str.Replace("Æ", "AE");
  str = str.Replace("æ", "ae");

  // Esperanto http://en.wikipedia.org/wiki/Esperanto_orthography
  from = "ĈĜĤĴŜŬĉĝĥĵŝŭ".ToCharArray();
  to = "CXGXHXJXSXUXcxgxhxjxsxux".ToCharArray();
  for (int i = 0; i < from.Length; i++) {
    str = str.Replace(from[i].ToString(), "{0}{1}".Args(to[i*2], to[i*2+1]));
  }

  // Currencies.
  str = new Regex(@"([¢€£\$])([0-9\.,]+)").Replace(str, @"$2 $1");
  str = str.Replace("¢", "cents");
  str = str.Replace("€", "euros");
  str = str.Replace("£", "pounds");
  str = str.Replace("$", "dollars");

  // Ands
  str = str.Replace("&", " and ");

  // More aesthetically pleasing contractions
  str = str.Replace("'", "");
  str = str.Replace("’", "");

  // Except alphanumeric, everything else is a dash.
  str = new Regex(@"[^A-Za-z0-9-]").Replace(str, "-");

  // Remove dashes at the begining or end.
  str = str.Trim("-".ToCharArray());

  // Compact duplicated dashes.
  str = new Regex("-+").Replace(str, "-");

  // Let's url-encode just in case.
  return str.UrlEncode();
}

0
你可以使用HTTPUtility.UrlEncode,但这会编码所有内容,而不是替换或删除有问题的字符。因此,你的空格将变成+,'也将被编码。这不是一个解决方案,但可能是一个起点。

0

目标不是像XSS那样安全,而是安全的方式就像复制和粘贴URL一样,轻松输入,易于阅读,成为命令的一个字符串(不需要任何转义)等。 - pupeno

0

Ruby版本没有明确说明的一点(但原始的Perl版本有),它用于转换非罗马字符的算法是故意简单化的 - 在两个意义上都“好过没有”。例如,虽然它确实具有有限的能力来转换中文字符,但这完全是与上下文无关的 - 因此,如果您输入日语文本,则会得到乱码。

这种简单性的优点在于它非常容易实现。您只需要一个大的Unicode字符表及其相应的ASCII“等效项”。如果您决定自己实现此功能,则可以直接从Perl(或Ruby)源代码中提取此表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接