我对剃刀世界相对(更完全)是新手,并且不可避免地遇到了我的第一道障碍。我是一名Web开发人员,也是CMS Umbraco的新手,因此我一直在使用razor进行脚本编写。
我的问题相当简单;如何分割文本字符串以显示4个不同的单词/值,中间是逗号?
理想情况下,我想转向:
“为什么,不要,这,工作”的“为什么不要这个工作”,并且可能使事情变得复杂:“'为什么',不要,这个,工作”(用's围绕第一个词')我一直尝试从另一个线程使用此方法,但无济于事:
@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
}
}
答案 0 :(得分:2)
这并不是Razor特别要解决的问题。我认为这样做的最好方法是使用专用方法。简单的拆分不会做你想要的,因为你不知道要拆分的逻辑点,我也想不出一个简单的Regex解决方案。所以这是一个非常基本的例子,逐个字符地移动字符串来识别基本的单词边界:
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<string, IEnumerable<string>>
实例声明一个函数:
@{
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;
};
}
但即便如此也不是很好。它也不是正确分割字符串的防弹方式。