C# .NET正则表达式用于替换URL中的语言代码

C# .NET正则表达式用于替换URL中的语言代码,c#,.net,regex,C#,.net,Regex,如何在C函数中更改下面的正则表达式以获得如下所示的结果?由于语言代码的总数是固定的,我可以修改正则表达式模式而不是C代码吗?谢谢 C功能: 结果: 您可以使用语言名称和代码字典,并使用以下解决方案: var dct = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "english", "en"}, { "german", "de"}, { "italian", "it

如何在C函数中更改下面的正则表达式以获得如下所示的结果?由于语言代码的总数是固定的,我可以修改正则表达式模式而不是C代码吗?谢谢

C功能:

结果:


您可以使用语言名称和代码字典,并使用以下解决方案:

var dct = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) {
    { "english", "en"},
    { "german", "de"},
    { "italian", "it" }
};
//var url = "http://www.example.org/english/"; // http://en.example.org/
var url = "https://www.example.org/german/"; // https://de.example.org/
string pat = @"(?i)^(https?://)www\.(.*?)/(english|german|italian)/.*$";
Console.WriteLine(Regex.Replace(url, pat, m => {
        var val = "";   
        return dct.TryGetValue(m.Groups[3].Value, out val) ?
          $"{m.Groups[1].Value}{dct[m.Groups[3].Value]}.{m.Groups[2].Value}/" :
          $"{m.Groups[1].Value}{m.Groups[3].Value}.{m.Groups[2].Value}/";
      }
    )
);

模式匹配

?i-使正则表达式不区分大小写 ^-字符串的开头 https?:/-组1:a http://或https:// www\.-www.wrap with?:。。。?有选择地匹配它 .*? - 第2组:任何0+字符,尽可能少 /-a/ 英语|德语|意大利语-第3组:三种选择中的任何一种 /-a/ .*-该行的其余部分 $-字符串的结尾。
匹配后,dct.TryGetValuem.Groups[3]。值,out val?检查组3值是否可以映射到语言代码,如果可以,则在替换中使用dct[m.Groups[3].value]。否则,m.Groups[3]值将按原样使用。

您需要一个映射,从中可以派生正则表达式

private static readonly Dictionary<string, string> LangMap = new Dictionary<string, string>
{
    { "english", "en" },
    { "german", "de" },
    { "italian", "it" }
};

private static readonly string LangString = string.Join("|", LangMap.Keys.Select(x => x).ToArray());
private static readonly Regex LangPattern = new Regex($@"(?<=https://www\.(.*?)/)({LangString})(?=/.*$)");

public static string GetSubdomain(string url)
{
    var match = LangPattern.Match(url);
    return $"http://{LangMap[match.Groups[2].Value]}.{match.Groups[1].Value}/";
}
在一般情况下,我怀疑正则表达式是否有用;我们应该首先检测培养基,假设您坚持ISO 3166:

然后才转换uri:

public static string GetSubdomain(string address) {
  CultureInfo culture = CultureFormAddress(address);

  if (culture == CultureInfo.InvariantCulture)
    return address;

  Uri uri = new Uri(address);

  return string.Concat(
    $"{uri.Scheme}://{culture.Name}.",
      uri.Host.StartsWith("www.", StringComparison.OrdinalIgnoreCase) 
        ? uri.Host.Substring("www.".Length) 
        : uri.Host,
      "/",
      string.Join("/", uri.LocalPath
        .Split('/')
        .SkipWhile(item => string.IsNullOrEmpty(item))
        .Skip(1))
      );
} 
例如,让我们提供一个未知的文化-俄语和scheme-Ftp。让我们添加本地路径-bla bla bla:

// ftp://ru.example.org/bla-bla-bla
GetSubdomain("ftp://www.example.org/russian/bla-bla-bla");
其他测试:

  string[] tests = new string[] {
    "http://www.example.org/english/",
    "http://www.example.org/german/",
    "http://www.example.org/italian/" };

  Console.Write(string.Join(Environment.NewLine, tests
    .Select(test => $"{test,-35} => {GetSubdomain(test)}")));
结果:

http://www.example.org/english/     => http://en.example.org/
http://www.example.org/german/      => http://de.example.org/
http://www.example.org/italian/     => http://it.example.org/

你必须编写一些代码:没有办法从germanYes生成de,如果前2个字符可以用来生成国家代码,我可以编写一个正则表达式而不需要映射。
// ftp://ru.example.org/bla-bla-bla
GetSubdomain("ftp://www.example.org/russian/bla-bla-bla");
  string[] tests = new string[] {
    "http://www.example.org/english/",
    "http://www.example.org/german/",
    "http://www.example.org/italian/" };

  Console.Write(string.Join(Environment.NewLine, tests
    .Select(test => $"{test,-35} => {GetSubdomain(test)}")));
http://www.example.org/english/     => http://en.example.org/
http://www.example.org/german/      => http://de.example.org/
http://www.example.org/italian/     => http://it.example.org/