Trim()。Split在Contains()中引起问题

时间:2019-01-14 08:48:52

标签: c# split trim

我得到一个字符串,并首先对其进行修剪,然后将其拆分并分配给string[]。然后,我将数组中的每个元素用于string.Contains()string.StartsWith()方法。有趣的是,即使字符串包含元素,Contains()也无法正常工作。 StartsWith()的情况也一样。有人对这个问题有任何想法吗?

附言::拆分后我修剪了字符串,问题解决了。

string inputTxt = "tasklist";
string commands = "net, netsh, tasklist";

string[] maliciousConsoleCommands = commands.Trim(' ').Split(',');

for (int i = 0; i < maliciousConsoleCommands.Length; i++) {
    if (inputTxt.StartsWith(maliciousConsoleCommands[i])) {
        return false;
    }
} 

//此代码有效,但不知道为什么以前的代码不起作用。

string[] maliciousConsoleCommands = commands.Split(',');

for (int i = 0; i < maliciousConsoleCommands.Length; i++) {
    if (inputTxt.StartsWith(maliciousConsoleCommands[i].Trim(' '))) {
        return false;
    }
}

我希望能正常工作,但拆分后可以通过修整来解决。

4 个答案:

答案 0 :(得分:4)

您的定界符不是逗号,而是逗号,后跟一个空格-因此,不用用','来分割,而只需用", "来分割即可:

string[] maliciousConsoleCommands = commands.Split(new string[] {", "});

这将返回没有前导空格的项目,因此修剪将是多余的。

答案 1 :(得分:2)

看来,您应该Trim 每个项目:

// ["net", "netsh, "tasklist"]
string[] maliciousConsoleCommands = commands
  .Split(',')                   // "net" " netsh", " tasklist" - note leading spaces
  .Select(item => item.Trim())  // removing leading spaces from each item
  .ToArray();

最后,如果您要测试inputTxt是否是恶意的:

if (commands
      .Split(',')
      .Select(item => item.Trim()) // You can combine Select and Any            
      .Any(item => inputTxt.StartsWith(item))
  return false;

答案 2 :(得分:0)

您提供的第一个代码将不起作用,因为您想修剪初始字符串,因此"net, netsh, tasklist"在修剪后将保持不变(没有前导和尾随空格),然后按逗号将其分隔开会产生条目,并带有前导空间。因此,您将得到意想不到的结果。您应该在 分割字符串后进行修剪。

第二个代码也将不起作用,因为您在Trim之后使用StartsWith,这将返回bool的值。您无法将Trim应用于bool,此代码甚至都不应编译。

答案 3 :(得分:0)

如果命令本身没有空格,则拆分的另一种方法是使用def printAll(self): pointer = self.head idx = 1 while pointer is not None: print(f'{idx}: {pointer.data} - {pointer.artist}') pointer = pointer.next idx += 1 本身作为分隔符,并丢弃空条目:

' '

这避免了每个字符串操作命令生成的临时字符串。

为了使代码正常工作,您将对每个命令使用var maliciousConsoleCommands = commands.Split(new[]{',',' '},StringSplitOptions.RemoveEmptyEntries) .ToArray(); ,而不是使用Contains

StartWith

甚至:

var isSuspicious = maliciousCommands.Any(cmd=>input.Contains(cmd));

如果您有多个命令,或者输入的文本很大,这会变得很慢

正则表达式替代

一种更快的技术是使用正则表达式。这样执行 lot 的速度比搜索单个关键字要快:

var isSuspicious = maliciousCommands.Any(input.Contains);

正则表达式是线程安全的,这意味着它们可以创建一次并由不同的线程/请求重用。

通过使用var regex=new Regex("net|netsh|tasklist"); var isSuspicious=regex.IsMatch(inputTxt); 而不是Match/Matches,正则表达式可以返回检测到的实际关键字:

IsMatch

可以使用单个var detection=regex.Match(inputTxt); if (detection.Success) { var detectedKeyword=detection.Value; .... } 或可以处理任何空格字符的另一个正则表达式将原始的逗号分隔列表转换为正则表达式:

String.Replace(", ")

仅检测整个单词

string commands = "net , netsh, \ttasklist"; var pattern=Regex.Replace(commands,@"\s*,\s*","|").Dump(); var regex=new Regex(pattern); 和原始正则表达式都将与Containstasklist1匹配。如果模式被单词定界符tasklist包围,则只能匹配整个单词:

\b

这将匹配@"\b(" + pattern + @")\b" tasklist,但拒绝net