C# 字符串中的C字符计数并在字符串中添加句点
这一条非常简单,但我只是不知道如何在没有foreach循环的情况下完成它 我想做的是放置一个句号。在每个字符串的第6个字符之后 输入: ads234adf4234asd dfasd234asdf45 rte3443 fdf323ggt vgdfg767575 sdgsdfgdfg756756 输出: ads234.adf4234asd dfasd2.34asdf45 rte344.3 fdf323.ggt vgdfg7.67575 sdgsdf.gdfg756756C# 字符串中的C字符计数并在字符串中添加句点,c#,C#,这一条非常简单,但我只是不知道如何在没有foreach循环的情况下完成它 我想做的是放置一个句号。在每个字符串的第6个字符之后 输入: ads234adf4234asd dfasd234asdf45 rte3443 fdf323ggt vgdfg767575 sdgsdfgdfg756756 输出: ads234.adf4234asd dfasd2.34asdf45 rte344.3 fdf323.ggt vgdfg7.67575 sdgsdf.gdfg7
如何执行此操作?对于可用于获得所需结果的每个字符串:
string s = "ads234adf4234asd";
s = s.Insert(6, ".");
如果要避免编写显式for循环,可以尝试LINQ:
string[] result = lines
.Select(s => s.Insert(6, "."))
.ToArray();
注意,这避免了foreach,但并没有避免循环——Select的实现中仍然有一个循环
如果您不希望程序在收到长度小于等于5的字符串时崩溃,而只是返回未更改的字符串,请尝试以下操作:
string[] result = lines
.Select(s => s.Length >= 6 ? s.Insert(6, ".") : s)
.ToArray();
可以使用“模数”操作符来实现这一点。e、 g
string myString = "abcdefghijklmnopqrstuvwxyz";
string newString = "";
for (int i = 0; i < myString.Length; i++)
{
if (i !=0 && i % 6 == 0)
{
newString += ".";
}
newString += myString[i];
}
我看不出一种不循环的方法——如果将其存储为单个字符数组,则可以单步遍历每个字符,并在找到的每个返回/换行字符后插入一个句点6个字符 编辑:可能误解了每一行的循环。。。您是指从一行到另一行的每个循环,还是通过每行中的字符进行循环?未经测试,但这可能有效:
如果你把字符串的长度除以6,你就知道要加多少个句点。所以
// -1 to account for i = 6 in the loop to start
int numPeriods = ( str.Length / 6 ) - 1;
// we increment the index by 7 to account for the period we added
for( int index = 6, i = 0; i < numPeriods; index += 7, ++i )
{
str = str.Insert( index, "." );
}
我相信还有更优雅的方式,但我必须回去工作
另外,您的书面请求和示例不是一回事。你说
我要做的是在字符串中的每6个字符后面放置一个“.”
但您的示例显示在索引6处为每行添加一个句点。它是哪一个?我将重用我之前介绍的一些代码,这些代码将IEnumerable拆分为多个页面:
static class EnumerableExtensions {
public static IEnumerable<IEnumerable<T>> GetPages<T>(
this IEnumerable<T> source,
int pageSize
) {
var e = source.GetEnumerator();
while (e.MoveNext()) {
int count = pageSize - 1;
List<T> list = new List<T>(pageSize) { e.Current };
while (count > 0 && e.MoveNext()) {
list.Add(e.Current);
count--;
}
yield return list;
}
}
}
当然,有一些回路埋在那里,我真的无法理解你想要避免。但是,如果确实必须避免循环,则可以递归执行此操作:
static string SplitAndInsert(string s, int afterEvery, char insertCharacter) {
if (s.Length < afterEvery) {
return s;
}
else {
return
s.Substring(0, afterEvery) +
insertCharacter +
SplitAndInsert(
s.Substring(afterEvery, s.Length - afterEvery),
afterEvery,
insertCharacter
);
}
}
我认为循环是最好的方法,也许你可以用LINQ使你的代码更干净:
var linq = from text in strings
where text.Length > 6
select text.Insert(6, ".");
下面的正则表达式将插入一个。每行第6个字符后:
Regex.Replace(yourInputString, "^(?<before>.{6})(?<after>.*)$", @"${before}.${after}", RegexOptions.Multiline);
为什么要避免循环?您的示例仅显示在第6个字符后添加句点,而不是每6个字符添加一个句点。你想要的是哪一个?如果输入字符串短于六个字符,会发生什么情况?@tvanfosson:我认为字符串中的每六个字符后面都是指字符串中的每六个字符后面。更好的措辞应该在每个字符串的第6个字符之后。所以我认为他的例子是正确的,只是问题的措辞有点让人困惑。@Mark:我相信我在我的解决方案中解决了这个问题。字符串是不可变的-Insert方法返回一个新字符串。Mike不是还需要跳过每一行吗?他说foreach,而不是for=DInventive,但是为什么要让OP迭代整个字符串呢?对不起,我删除了我的评论,因为我认为我的评论有错误的结尾:For ref:我问这是否意味着Mike仍然需要遍历每一行。你为什么不使用插入方法而不是子字符串?@Chris Dunaway:因为我不知道这个方法。我现在已经修好了。谢谢你教我新东西!
static string SplitAndInsert(string s, int afterEvery, char insertCharacter) {
if (s.Length < afterEvery) {
return s;
}
else {
return
s.Substring(0, afterEvery) +
insertCharacter +
SplitAndInsert(
s.Substring(afterEvery, s.Length - afterEvery),
afterEvery,
insertCharacter
);
}
}
var linq = from text in strings
where text.Length > 6
select text.Insert(6, ".");
Regex.Replace(yourInputString, "^(?<before>.{6})(?<after>.*)$", @"${before}.${after}", RegexOptions.Multiline);