删除用户输入字段中过多的空格

本文关键字:空格 用户 输入 字段 删除 | 更新日期: 2023-09-27 18:31:05

在我的控制器方法中,用于处理(潜在的敌对)用户输入字段,我有以下代码:

string tmptext = comment.Replace(System.Environment.NewLine, "{break was here}"); //marks line breaks for later re-insertion
tmptext = Encoder.HtmlEncode(tmptext);
//other sanitizing goes in here 
tmptext = tmptext.Replace("{break was here}", "<br />");
var regex = new Regex("(<br /><br />)''1+");
tmptext = regex.Replace(tmptext, "$1");

我的目标是为典型的非恶意使用保留换行符,并以安全的 html 编码字符串显示用户输入。 我接受用户输入,解析换行符并在换行符处放置分隔符。我执行 HTML 编码并重新插入中断。(我可能会将其更改为将段落重新插入为 p 标签而不是 br,但现在我使用的是 br)

现在实际上插入真正的 html 中断打开了一个微妙的漏洞:Enter 键。regex.replace 代码用于去除恶意用户,只需站在 Enter 键上并用垃圾填充页面。

这是对只有白色的大垃圾洪水的修复,但仍然让我容易受到滥用,例如在页面上输入一个字符、两个换行符、一个字符、两个换行符。

我的问题是确定这是滥用并在验证时失败的方法。我担心可能没有一个简单的程序方法来做到这一点,而是需要启发式技术或贝叶斯滤波器。希望有人有一个更简单,更好的方法。

编辑:也许我在问题描述中不清楚,正则表达式处理连续查看多个换行符并将它们转换为一两个。 这个问题解决了。真正的问题是将合法文本与垃圾洪水区分开来:

一个

一个

一个

。想象一下其中的 1000 个...

一个

一个

一个

一个

删除用户输入字段中过多的空格

一个

随机建议,灵感来自slashdot.org的评论过滤器:使用System.IO.Compression.DeflateStream压缩你的用户输入,如果它与原始输入相比太小(你必须做一些实验才能找到一个有用的截止点),拒绝它。

我会HttpUtility.HtmlEncode字符串,然后将换行符转换为<br/>.

HttpUtility.HtmlEncode(subject).Replace("'r'n", "<br/>").Replace("'r", "<br/>").Replace("'n", "<br/>");

此外,您应该在输出给用户时执行此逻辑,而不是在数据库中保存时。 我对数据库进行的唯一验证是确保它已正确转义(除了正常的业务规则)。

编辑:但是,要解决实际问题,您可以使用正则表达式事先用单个换行符替换多个换行符。

subject = Regex.Replace(@"('r'n|'r|'n)+", @"'n", RegexOptions.Singleline);

我不确定你是否需要RegexOptions.Singleline.

听起来你很想用正则表达式尝试一些"聪明"的东西,但 IMO 最简单的方法是循环访问字符串的字符,将它们复制到 StringBuilder,边走边过滤。

任何失败的字符。IsWhiteSpace() 测试不会被复制。(如果其中一个是换行符,则插入
,并且在点击非空格字符之前不允许再添加任何
)。

编辑

如果你想阻止用户输入任何旧的废话,现在就放弃。你永远不会找到一种过滤方式,如果用户真的想的话,他们无法在不到一分钟的时间内找到解决方法。

最好限制输入中的换行符数或字符总数。

想想做一些聪明的事情来净化"不良输入"需要付出多少努力,然后考虑这种情况发生的可能性有多大。可能没有意义。可能您真正需要的所有清理都是为了确保数据是合法的(对于您的系统来说不会太大而无法处理,所有危险字符都被剥离或逃脱等)。(这正是论坛有人工版主的原因,他们可以根据任何适当的标准过滤帖子)。

这不是最有效的处理方式,也不是最聪明的方法(免责声明),
但是,如果你的文本不是太大,那就无关紧要了,也没有任何更聪明的算法(注意:很难检测到类似char'nchar'nchar'n...的东西,尽管你可以在 len 上设置一个限制)

你可以只Split白色字符(添加你能想到的任何字符,除了 ') - 然后只用一个空格Join,然后在<br />上拆分(以获得行) - 用line.Length > 2连接。在连接线路时,您可以测试DistinctUntilChanged例如或其他东西。

为了加快速度,您可以使用更有效的算法进行迭代,逐个字符,使用 IndexOf 等。

同样不是处理这个问题的最有效或最完美的方法,但会给你一些快速的东西。

编辑:过滤"相同的行" - 您可以使用例如 Ix - Interactive extensions - 这是来自<br />(我认为请参阅 NuGet Ix-实验),它应该连续过滤"相同行"+ 您可以为它们添加行测试。

与其尝试用过滤文本替换换行符,然后尝试使用正则表达式,为什么不在插入HttpUtility.HtmlEncode标签之前清理您的数据?不要忘记先用CC_14清理输入。

为了连续处理多条短线,这是我最好的尝试:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
class Program {
  static void Main() {
    // Arbirary cutoff used to join short strings.
    const int Cutoff = 6;
    string input =
      "'r'n'r'n'n'r'r'r'n'nthisisatest'r'nstring'r'nwith'nsome'r'n" + 
      "unsanatized'r'nbreaks'r'nand'ra'nsh'nor'nt'r'n'na'na'na'na" +
      "'na'na'na'na'na'na'na'na'na'na'na'na'na'na'na'na'na";
    input = (input ?? String.Empty).Trim(); // Don't forget to HtmlEncode it.
    StringBuilder temp = new StringBuilder();
    List<string> result = new List<string>();
    var items = input.Split(
                        new[] { ''r', ''n' },
                        StringSplitOptions.RemoveEmptyEntries)
                     .Select(i => new { i.Length, Value = i });
    foreach (var item in items) {
      if (item.Length > Cutoff) {
        if (temp.Length > 0) {
          result.Add(temp.ToString());
          temp.Clear();
        }
        result.Add(item.Value);
        continue;
      }
      if (temp.Length > 0) { temp.Append(" "); }
      temp.Append(item.Value);
    }
    if (temp.Length > 0) {
      result.Add(temp.ToString());
    }
    Console.WriteLine(String.Join("<br />", result));
  }
}

生成以下输出:

thisisatest<br />string with some<br />unsanatized<br />breaks and a sh or t a a
 a a a a a a a a a a a a a a a a a a a

我相信你已经想出了这个解决方案,但不幸的是,你所要求的不是很简单。

对于那些感兴趣的人,这是我的第一次尝试:

using System;
using System.Text.RegularExpressions;
class Program {
  static void Main() {
    string input = "'r'n'r'n'n'r'r'r'n'nthisisatest'r'nstring'r'nwith'nsome" +
                   "'r'nunsanatized'r'nbreaks'r'n'r'n";
    input = (input ?? String.Empty).Trim().Replace("'r", String.Empty);
    string output = Regex.Replace(
                      input,
                      "'''n+",
                      "<br />",
                      RegexOptions.Multiline);
    Console.WriteLine(output);
  }
}

生成以下输出:

thisisatest<br />string<br />with<br />some<br />unsanatized<br />breaks