用新的URL替换旧URL

时间:2017-06-30 10:36:07

标签: c# regex

我有一个包含一些网址的数据库中的字符串。我正在尝试用新的URL替换旧的URL。因为包含url的字符串格式为{s:5:"hello"},所以我还需要用新的字符串替换旧的字符串长度。

我试过

var url    = "http://localhost/arearaf";
var text   = "somelongstring; 35; '%site_url%'; s:46:\"%site_url%/wp-content/uploads/2017/06/logo.png\"; someotherlongstring; s:54:\"%site_url%/wp-content/uploads/2017/06/logo-150x150.png\";";
var result = Regex.Replace(text, @"s:\d+:\" + "\"%site_url%(.*?)\";", "s:" + (url.Length + "$1".Length) + @":\" + "\"" + url + "$1" + @"\" + "\";");

导致

"somelongstring; 35; '%site_url%'; s:26:\"http://localhost/arearaf/wp-content/uploads/2017/06/logo.png\"; someotherlongstring; s:26:\"http://localhost/arearaf/wp-content/uploads/2017/06/logo-150x150.png\";"

但应该是

"somelongstring; 35; '%site_url%'; s:60:\"http://localhost/arearaf/wp-content/uploads/2017/06/logo.png\"; someotherlongstring; s:68:\"http://localhost/arearaf/wp-content/uploads/2017/06/logo-150x150.png\";"

"$1".Length显然不会返回"/wp-content/uploads/2017/06/logo.png".Length。如何为每次替换获取捕获组的长度?我也正确处理问题了吗?如果没有,我该怎么办?

<小时/> 这种格式{s:5:"hello"}不具有名称或其他内容吗?我不能谷歌。我能找到的最接近的是CMS,它代表内容管理系统,我想?不过,还不够。

1 个答案:

答案 0 :(得分:2)

使用匹配评估程序并按以下方式修改代码:

var url    = "http://localhost/arearaf";
var text   = "somelongstring; 35; '%site_url%'; s:46:\"%site_url%/wp-content/uploads/2017/06/logo.png\"; someotherlongstring; s:54:\"%site_url%/wp-content/uploads/2017/06/logo-150x150.png\";";
var result = Regex.Replace(text, "s:\\d+:\"%site_url%(.*?)\";", m =>
        $"s:{url.Length + m.Groups[1].Value.Length}:\"{url}{m.Groups[1].Value}\";");
Console.WriteLine(result);
// => somelongstring; 35; '%site_url%'; s:60:"http://localhost/arearaf/wp-content/uploads/2017/06/logo.png"; someotherlongstring; s:68:"http://localhost/arearaf/wp-content/uploads/2017/06/logo-150x150.png";

请参阅online demo

模式s:\d+:"%site_url%(.*?)";):

  • s: - 子字符串s:
  • \d+ - 一个或多个数字(使用RegexOptions.ECMAScript编译只匹配ASCII数字)
  • :" - :"%site_url%子字符串
  • (.*?) - 第1组捕获除换行符之外的任何0个或多个字符(如果您还需要匹配换行符,则传递RegexOptions.Singleline
  • "; - 子字符串";

匹配计算器将匹配对象传递给插值字符串文字:

  • $" - 插值字符串文字开头
  • s: - 文字s:
  • {url.Length + m.Groups[1].Value.Length} - 内插部分,其中URL长度和第1组值长度相加并转换为字符串
  • :\" - :" substring
  • {url} - url var value
  • {m.Groups[1].Value} - 第1组值
  • \"; - ";子字符串
  • " - 字符串文字的结尾。

对于没有内插字符串文字支持的旧环境,请使用string.Format

var result = Regex.Replace(text, "s:\\d+:\"%site_url%(.*?)\";", m =>
  string.Format("s:{0}:\"{1}{2}\";", 
    url.Length + m.Groups[1].Value.Length, url, m.Groups[1].Value));