C# 删除字符串中的附加间距[最快方式]
我需要删除字符串中的所有附加空格。 我使用正则表达式来匹配字符串,并用其他字符串替换匹配字符串。 为了更好地理解,请参见以下示例: 3个输入字符串:C# 删除字符串中的附加间距[最快方式],c#,regex,performance,C#,Regex,Performance,我需要删除字符串中的所有附加空格。 我使用正则表达式来匹配字符串,并用其他字符串替换匹配字符串。 为了更好地理解,请参见以下示例: 3个输入字符串: Hello, how are you? Hello , how are you? Hello , how are you ? 这是3个字符串,应该由一个模式正则表达式匹配。 它看起来像这样: Hello\s*,\s+how\s+are\s+you\s*? 它工作正常,但存在性能问题。 如果我有很多模式(~20k
Hello, how are you?
Hello , how are you?
Hello , how are you ?
这是3个字符串,应该由一个模式正则表达式匹配。
它看起来像这样:
Hello\s*,\s+how\s+are\s+you\s*?
它工作正常,但存在性能问题。
如果我有很多模式(~20k),并尝试执行每个模式,那么它的运行速度非常慢(3-5分钟)
也许有更好的方法?
例如,使用一些3d派对LIB
UPD:各位,这个问题不是关于如何做到这一点。它是关于如何以最佳性能完成此任务的。:)强>
让我详细解释一下。主要目标是标记化文本。(用特殊符号替换某些令牌) 例如,我有一个标记“很好的尝试”。 然后我输入文本“这是很好的尝试”。 结果:“这是@tokenizedtext@”,其中@tokenizedtext@包含一些特殊符号。在这种情况下没关系 接下来是“迈克说这是一次很好的尝试”。 结果应该是“Mike说这是一个@tokenizedtext@”。 我认为主要思想是明确的 所以我可以有很多代币。当我处理它时,我将令牌从“nice-try”转换为模式“nice\s+try”。并尝试用此模式替换输入文本。 它很好用。但是如果代币中有更多的空格和标点符号,那么我的正则表达式就变大了,运行速度也很慢
你对解决这个问题有什么建议(技术或逻辑)?如果只是空间问题 试试这个 资料来源: 以以下方式替换正则表达式:
string resultString = null;
try {
resultString = Regex.Replace(subjectString, @"\s+", " ", RegexOption.Compiled);
} catch (ArgumentException ex) {
// Syntax error in the regular expression
}
嗯,这些问题真的很困扰我们。使用这个代码,我相信你会得到你所要求的结果。此命令删除任何字符串之间的任何额外空格
cleanString= Regex.Replace(originalString, @"\s", " ");
希望他能为你工作。谢谢
因为这是一条指令。它将使用更少的CPU资源,从而减少CPU时间,从而最终提高性能。因此,A/C对我来说,这种方法在性能方面是最好的。您使用的是一个非常复杂的正则表达式。简化正则表达式肯定会提高性能
使用
\s+
并将其替换为单个空格我可以建议一些解决方案
首先,避免使用静态的Regex
方法。创建它的一个实例(并存储它,不要每次替换都调用构造函数!),如果可能的话,使用RegexOptions.Compiled
。这会提高你的表现
第二,你可以试着回顾你的模式。我会做一些分析,但我目前还不确定:
@(?这可能适合您。它应该非常快。请注意,它还会删除字符串末尾的空格;这可能不是您想要的
using System;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(">{0}<", RemoveExtraSpaces("Hello, how are you?"));
Console.WriteLine(">{0}<", RemoveExtraSpaces("Hello , how are you?"));
Console.WriteLine(">{0}<", RemoveExtraSpaces("Hello , how are you ?"));
}
public static string RemoveExtraSpaces(string text)
{
var buffer = new char[text.Length];
bool isSpaced = false;
int n = 0;
foreach (char c in text)
{
if (c == ' ')
{
isSpaced = true;
}
else
{
if (isSpaced)
{
if ((c != ',') && (c != '?'))
{
buffer[n++] = ' ';
}
isSpaced = false;
}
buffer[n++] = c;
}
}
return new string(buffer, 0, n);
}
}
}
使用系统;
名称空间演示
{
班级计划
{
静态void Main(字符串[]参数)
{
Console.WriteLine(“>{0}{0}{0}我自己的东西:
查找WhiteSpacechar在字符串中的所有位置
private static IEnumerable<int> GetWhiteSpacePos(string input)
{
int iPos = -1;
while ((iPos = input.IndexOf(" ", iPos + 1, StringComparison.Ordinal)) > -1)
{
yield return iPos;
}
}
如果您向我们展示完整的方法,我们可能会指出其中的慢点,但就目前情况而言,您只是给出了一些小片段,这些片段本身并没有真正的帮助。例如,您可能会错误地将20k中的每一个都与其他方法进行比较,而不是将其与一个成功的方法进行比较,这显然要慢得多!您有没有看看这个问题:-它详细解释了慢速c#regexp你想做什么?你的预期结果是什么?@alexi-请解释一下你期望得到什么样的输出在再次回复更新时,如果你不向我们展示你的代码,我们无法提高你的性能!这里不需要分组,或者只需要boldRegex。替换(原始字符串@“\s+”,“”);**bold**将完成此工作。它将所有空格转换为单个空格。您的方法效率低下且不可读。它大约比编译器正则表达式慢三倍。@Eve:我打赌您对调试生成而不是发布生成进行了计时。@MatthewWatson否。最糟糕的问题是while
块。它创建了一个新的t实例在其中找到的每两个空格对应一个字符串。哦,对了,你是指用法块中的代码,而不是replaceX()的实现。@MatthewWatson该实现也有问题。它调用ToUpper
两次,并创建两个新字符串(加上返回字符串)。此外,它还创建了char
数组(我还没有试着读它的实际用途)。这都是开销。不幸的是,我不能使用编译的
选项。(@AlexeiMalashkevich如果没有编译
选项,速度会稍微慢一点,但速度还是相当快。我会尝试另一种方法。@AlexeiMalashkevich我写了一个方法,应该比其他建议的快。请尝试一下。看起来很有趣。我们会测试这个。现在是最好的答案。很抱歉延迟。我们会在一周内测试它一两个。
var s = "Hello , how are you?";
var pattern = @"\s+";
var regex = new Regex(pattern, RegexOptions.Compiled);
var replaced = regex.Replace(s, " ");
static unsafe string TrimInternal(string input)
{
var length = input.Length;
var array = stackalloc char[length];
fixed (char* fix = input)
{
var ptr = fix;
var counter = 0;
var lastWasSpace = false;
while (*ptr != '\x0')
{
//Current char is a space?
var isSpace = *ptr == ' ';
//If it's a space but the last one wasn't
//Or if it's not a space
if (isSpace && !lastWasSpace || !isSpace)
//Write into the result array
array[counter++] = *ptr;
//The last character (before the next loop) was a space
lastWasSpace = isSpace;
//Increase the pointer
ptr++;
}
return new string(array, 0, counter);
}
}
var s = TrimInternal("Hello , how are you?");
using System;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(">{0}<", RemoveExtraSpaces("Hello, how are you?"));
Console.WriteLine(">{0}<", RemoveExtraSpaces("Hello , how are you?"));
Console.WriteLine(">{0}<", RemoveExtraSpaces("Hello , how are you ?"));
}
public static string RemoveExtraSpaces(string text)
{
var buffer = new char[text.Length];
bool isSpaced = false;
int n = 0;
foreach (char c in text)
{
if (c == ' ')
{
isSpaced = true;
}
else
{
if (isSpaced)
{
if ((c != ',') && (c != '?'))
{
buffer[n++] = ' ';
}
isSpaced = false;
}
buffer[n++] = c;
}
}
return new string(buffer, 0, n);
}
}
}
private static IEnumerable<int> GetWhiteSpacePos(string input)
{
int iPos = -1;
while ((iPos = input.IndexOf(" ", iPos + 1, StringComparison.Ordinal)) > -1)
{
yield return iPos;
}
}
string original_string = "Hello , how are you ?";
var poss = GetWhiteSpacePos(original_string).ToList();
int startPos;
int endPos;
StringBuilder builder = new StringBuilder(original_string);
for (int i = poss.Count -1; i > 1; i--)
{
endPos = poss[i];
while ((poss[i] == poss[i - 1] + 1) && i > 1)
{
i--;
}
startPos = poss[i];
if (endPos - startPos > 1)
{
builder.Remove(startPos, endPos - startPos);
}
}
string new_string = builder.ToString();