【问题标题】:Building a new path-like string from an existing one从现有字符串构建新的类似路径的字符串
【发布时间】:2019-03-22 08:26:54
【问题描述】:

我想修改一个看起来像

的源字符串
"one.two.three" 

并将其转换为带有斜线的字符串,以将其用作具有以下结构的文件夹字符串:

"one\one.two\one.two.three"

你知道比我下面的解决方案更优雅的方法吗?我对我的 for 循环不太满意。

var folder = "one.two.three";
var folderParts = folder.Split('.');
var newFolder = new StringBuilder();
for (int i = 0; i < folderParts.Length; i++)
{
    for (int j = 0; j < i; j++)
    {
       if (j == 0)
       {
          newFolder.Append("\\");
       }

       newFolder.Append($"{folderParts[j]}.");
    }

    newFolder.Append(folderParts[i]);
}

【问题讨论】:

  • got 可以通过 Aggregate 实现这一点,但我不能完全确定。

标签: c# .net string


【解决方案1】:

您可以使用正则表达式非常简洁地做到这一点

var newFolder = Regex.Replace(folder, @"\.", @"\$`.");

这在每个时期都匹配。每次找到句点时,它都会插入一个反斜杠,然后在匹配之前插入整个输入字符串 ($`)。我们必须在最后再次添加句点。

因此,步骤是( 表示在该步骤由替换插入的文本):

  1. 在第一节比赛。 one&lt;\one&gt;.two.three
  2. 第二节比赛。 one\one.two&lt;\one.two&gt;.three
  3. 结果:one\one.two\one.two.three

对于奖励积分,请使用Path.DirectorySeparatorChar 以获得跨平台的正确性。

var newFolder = Regex.Replace(folder, @"\.", $"{Path.DirectorySeparatorChar}$`.")

这是另一种 linqy 方式:

var a = "";
var newFolder = Path.Combine(folder.Split('.')
    .Select(x => a += (a == "" ? "" : ".") + x).ToArray());

【讨论】:

  • 不错!只需替换即可获得结果
  • 当然,这是最短的解决方案,但如果您不是正则表达式极客,则很难阅读。谢谢你的详细解释! :)
  • 也感谢您对跨平台兼容性的提示。
  • @Christoph 同意。我说它很简洁,并不是说它一定是可读的!老实说,我会针对这些解决方案中的任何一个写评论,说明它做了什么。您可以在这一行中添加几行额外的 cmets,以解释它是如何工作的,直到它得到下一个最简单的答案。
【解决方案2】:

你可以试试Linq

  string folder = "one.two.three";
  string[] parts = folder.Split('.');

  string result = Path.Combine(Enumerable
    .Range(1, parts.Length)
    .Select(i => string.Join(".", parts.Take(i)))
    .ToArray());

  Console.Write(newFolder);

结果:

 one\one.two\one.two.three 

【讨论】:

  • 也许在第一个 string.Join 上使用 Path.Combine,以实现跨平台?
  • @canton7:谢谢! Path.Combine 在上下文中要好得多
【解决方案3】:

您可以像这样在一个循环中只前进:

    var folder = "one.two.three";
    var newFolder = new StringBuilder();

    int index = -1;
    while (index + 1 < folder.Length) {
        index = folder.IndexOf('.', index + 1);
        if (index < 0) {
            newFolder.Append(folder);
            break;
        }
        else {
            newFolder.Append(folder, 0, index);
            newFolder.Append(Path.DirectorySeparatorChar);
        }
    }

你可以try it out here

【讨论】:

    【解决方案4】:

    与其先拆分字符串,不如从现有的开始并减少它更优雅:

    var folder = "one.two.three";
    var newFolder = string.Empty;
    for (var f = folder; f.Any(); f = f.Remove(Math.Max(f.LastIndexOf('.'), 0)))
        newFolder = Path.Combine(f, newFolder);
    
    Console.WriteLine(newFolder);
    

    输出:

    one\one.two\one.two.three 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-11
      • 1970-01-01
      相关资源
      最近更新 更多