假设我有以下字符串:
string s = "A B C D TESTTEST BLA BLA TEST TEST2"
然后我需要以下内容:
"A B C D TESTTEST BLA BLA TEST TEST2"
所以规则是:
a)用
替换每隔一个空格(非空间字符之间的)
b)如果最后一个空格被
替换,请尝试将其向后移动(如果可能)一步,以便强制空间不触及下一个单词。
背景:
我想用它将数据从数据库打印到我的网站。但我想优化强制空间以减少占用空间。我还希望最后一个强制空间不要触及下一个单词(如果可能的话),这样一些搜索引擎就可以更容易地抓住这个单词了。
我是否需要循环遍历该字符串中的每个字符并计算出现次数还是更容易,更快速,更奇特的方式?
谢谢,两种解决方案都很完美。
所以我做了一个基准来确定接受哪种解决方案:
@Guffa,你的解决方案需要22秒才能完成1百万次运行 @Timwi,您的解决方案需要7秒才能完成100万次
我会给你一个upvote,但我会接受Timwi的解决方案。
答案 0 :(得分:4)
Let’s use a regular expression!
var input = "A B C D TESTTEST BLA BLA TEST TEST2";
var output = Regex.Replace(input, @" +", m =>
m.Length == 2 ? " " :
m.Length % 2 == 1 ? " ".Repeat(m.Length / 2) + " " :
" ".Repeat(m.Length / 2 - 1) + " ");
这使用了我写的string.Repeat
扩展方法:
/// <summary>
/// Concatenates the specified number of repetitions of the current string.
/// </summary>
/// <param name="input">The string to be repeated.</param>
/// <param name="numTimes">The number of times to repeat the string.</param>
/// <returns>A concatenated string containing the original string the specified number of times.</returns>
public static string Repeat(this string input, int numTimes)
{
if (numTimes == 0) return "";
if (numTimes == 1) return input;
if (numTimes == 2) return input + input;
var sb = new StringBuilder();
for (int i = 0; i < numTimes; i++)
sb.Append(input);
return sb.ToString();
}
顺便说一句,如果通过“节省空间”指的是带宽/存储空间,则可以使用"\xa0"
代替" "
来使其更加紧凑,这在HTML中是等效的。
答案 1 :(得分:3)
你可以这样做:
s = String.Concat(
Regex.Split(s, "( +)")
.Select((p, i) => i % 2 == 0 ? p :
String.Concat(
Enumerable.Repeat(" ", p.Length<3 ? p.Length-1 : p.Length/2-1)
.ToArray()) +
(p.Length % 2 == 1 ? " " : "") +
(p.Length > 2 ? " " : ""))
.ToArray()
);
答案 2 :(得分:0)
s.Replace(" ", " ");