【问题标题】:How can I split a textstring using razor (in Umbraco)?如何使用剃刀(在 Umbraco 中)拆分文本字符串?
【发布时间】:2011-11-24 17:26:49
【问题描述】:

我对剃刀世界相对(更像是完全)新手,并且不可避免地遇到了我的第一个障碍。我是一名 Web 开发人员,也是 CMS Umbraco 的新手,因此我一直在使用 razor 编写脚本。

我认为我的问题相当简单;如何拆分文本字符串以显示 4 个不同的单词/值,中间有逗号?

理想情况下,我想变成这样的东西:

"WhyWontThisWork" 变成 "Why, Wont, This, Work" 并可能使事情复杂化:"'Why', Wont, This, Work"(在第一个单词周围带有 ')

我一直在另一个线程中尝试使用此方法,但无济于事:

@foreach (string s in "1,2,3".Split(',')) {
  @: s is equal to @s<br/>
}

通过尝试将此语法实现到我自己的脚本中,它看起来如下所示,因此它不起作用:

@inherits umbraco.MacroEngines.DynamicNodeContext
@{
    foreach (var x in Model.uctextstring.Split(',')) {
        @x.InnerText
    }
}

【问题讨论】:

    标签: asp.net razor split umbraco


    【解决方案1】:

    这并不是 Razor 专门解决的问题。我认为最好的方法是有一个专门的方法。简单的拆分不会做您想要的,因为您不知道拆分的逻辑点,而且我也想不出一个简单的正则表达式解决方案。所以这里有一个非常基本的例子,它逐个字符地遍历字符串来识别基本的单词边界:

    public static IEnumerable<string> SplitString(string value)
    {
      char last = char.MinValue;
      bool inWord = false;
      string word = string.Empty;
    
      foreach (char c in s)
      {
          if (char.IsLetter(c))
          {
              // Covers situations with apostrophised characters, e.g. 's
              if (last == '\'' && char.IsLetter(c) && inWord)
              {
                  word += last;
                  word += c;
                  yield return word;
    
                  word = string.Empty;
                  inWord = false;
              }
              else if (char.IsUpper(c) && !inWord)
              {
                  // Start of a new word.
                  word += c;
                  inWord = true;
              } 
              else if (char.IsUpper(c))
              {
                  // Return the last word.
                  yield return word;
    
                  // Start a new string.
                  word = string.Empty + c;
                  inWord = true;
              }
              else
              {
                  // Append to the current string.
                  word += c;
              }
          } 
          else
          {
              if (c == '\'' && inWord)
              {
                  // If we are at an apostrophe, set and then skip
                  last = c;
                  continue;
              }
    
              if (word.Length > 0)
              {
                  // Otherwise, if we have a previous word, return.
                  yield return word;
    
                  // Clear ready for the next word.
                  word = string.Empty;
                  inWord = false;
              }
          }
    
          last = c;
      }
    
      // If there is one more remaining word, return it.
      if (word.Length > 0)
          yield return word;
    }
    

    你可以加入/连接使用

    string result = string.Join(", ", SplitString(sentence));
    

    当我们使用yield 时,此方法利用编译器创建状态机的能力。这很好,因为我们可以通过字符流进行枚举,并在实际获取结果时返回。

    现在,这不会直接在 Razor 模板中工作,因为您需要声明一个模板方法。这样做的肮脏方式是使用Func&lt;string, IEnumerable&lt;string&gt;&gt; 实例声明一个函数:

    @{
        Func<string, IEnumerable<string>> splitter = s =>
        {
          char last = char.MinValue;
          bool inWord = false;
          string word = string.Empty;
    
          IList<string> words = new List<string>();
    
          foreach (char c in s)
          {
              if (char.IsLetter(c))
              {
                  if (last == '\'' && char.IsLetter(c) && inWord)
                  {
                      word += last;
                      word += c;
                      words.Add(word);
    
                      word = string.Empty;
                      inWord = false;
                  }
                  else if (char.IsUpper(c) && !inWord)
                  {
                      word += c;
                      inWord = true;
                  } 
                  else if (char.IsUpper(c))
                  {
                      words.Add(word);
    
                      word = string.Empty + c;
                      inWord = true;
                  }
                  else
                  {
                      word += c;
                  }
              } 
              else
              {
                  if (c == '\'' && inWord)
                  {
                      last = c;
                      continue;
                  }
    
                  if (word.Length > 0)
                  {
                      words.Add(word);
    
                      word = string.Empty;
                      inWord = false;
                  }
              }
    
              last = c;
          }
    
          if (word.Length > 0)
            words.Add(word);
    
          return words;
        };
      }
    

    但即使这样也不漂亮。这也不是正确拆分字符串的防弹方法。

    【讨论】:

    • 哇,谢谢你的回答,马修!只看代码就告诉我,我肯定已经超出了我的深度!
    猜你喜欢
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 2012-07-03
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    • 1970-01-01
    相关资源
    最近更新 更多