【问题标题】:Match non printable/non ascii characters and remove from text匹配不可打印/非 ascii 字符并从文本中删除
【发布时间】:2014-08-05 10:14:04
【问题描述】:

我的 JavaScript 很生锈,所以任何帮助都会很棒。我需要检测不可打印的字符(控制字符,如 SOH、BS 等)以及扩展的 ascii 字符(如字符串中的 Ž)并删除它们,但我不知道如何编写代码?

任何人都可以为我指出正确的方向吗?这是我目前所拥有的:

$(document).ready(function() {
    $('.jsTextArea').blur(function() {
        var pattern = /[^\000-\031]+/gi;
        var val = $(this).val();
        if (pattern.test(val)) {    
        for (var i = 0; i < val.length; i++) {
            var res = val.charAt([i]);
                alert("Character " + [i] + " " + res);              
        }          
    }
    else {
         alert("It failed");
     }

    });
});

【问题讨论】:

  • match 属性应该像这样调用:isNonAscii.match($(this).val())。程序不会神奇地知道您想将输入的值与正则表达式匹配。
  • 感谢您的意见。有道理,但是如何删除从文本框中的字符串中检测到的无效字符?
  • 我决定改变我的方法并采用服务器端解决方案(因为有时可以在客户端浏览器中关闭 javascript)
  • @GrantDoole:不要通过完全更改问题的代码来使现有答案无效。

标签: javascript regex control-characters


【解决方案1】:

您必须将模式(而不是字符串)分配给isNonAscii 变量,然后使用test() 检查它是否匹配。 test() 返回真或假。

$(document).ready(function() {
    $('.jsTextArea').blur(function() {
        var pattern = /[^\000-\031]+/gi;
        var val = $(this).val();
        if (pattern.test(val)) {
            alert("It matched");
        }
        else {
            alert("It did NOT match");
        }
    });
});

查看jsFiddle

【讨论】:

  • 非常感谢您的回复,但是如何检测无效字符,从字符串中删除 if 并在文本框中替换没有无效字符的新字符串?
  • 使用replace() 函数应该可以正常工作。您可以直接执行此操作,而不是那段代码。 @CasimiretHippolyte 的代码工作正常
【解决方案2】:

无需测试,直接处理文本框内容即可:

textBoxContent = textBoxContent.replace(/[^\x20-\x7E]+/g, '');

\x20-\x7E 的范围覆盖了 ascii 表的可打印部分。

代码示例:

$('.jsTextArea').blur(function() {
    this.value = this.value.replace(/[^\x20-\x7E]+/g, '');
});

【讨论】:

  • 感谢您的输入,但这不起作用,因为替换功能仅适用于可打印字符。 BS、SOH、ACK 等控制字符是不可见的,因此无法使用 .replace 方法获取。
  • @GrantDoole:多么疯狂的想法!仅仅因为一个字符不可打印并不意味着替换方法不会找到它! replace 方法适用于任何字符(可打印或不可打印)。
  • 真的吗?这很奇怪,因为我刚刚测试过它并没有用?你能告诉我吗?
  • @GrantDoole:我会在我的答案中添加一个小测试。
  • @GrantDoole:我忘记放g修饰符了,这可能是你没有得到预期结果的原因。
【解决方案3】:

要定位不属于可打印基本 ASCII 范围的字符,您可以使用这个简单的正则表达式:

[^ -~]+

说明:ASCII table 的前 128 个字符中,可打印范围以空格字符开始,以波浪号结束。这些是您要保留的字符。该范围用[ -~] 表示,不在该范围内的字符用[^ -~] 表示。这些是我们要替换的。因此:

result = string.replace(/[^ -~]+/g, "");

【讨论】:

  • 嗨,所有答案都非常好,但我即将解决。虽然 value.replace 效果很好,但这并不是我所需要的。我将用我目前所拥有的内容更新原始帖子。
  • 这将取代换行符/回车符,因此它不适用于多行文本。
  • 2019,这仍然是我遇到的最优雅的解决方案。是的,它删除了换行符、回车符和制表符,但对于那些真正试图去除这些字符的人来说,这个解决方案非常漂亮且易于人类阅读。
  • 嗨。仅供参考:这不适用于“şıç”(土耳其语)等特殊字符。将替换它们并打破这个词。
【解决方案4】:

对于那些遇到此问题并正在寻找“修复所有”解决方案的人...这就是我最终修复它的方式:

public static string RemoveTroublesomeCharacters(string inString)
{
    if (inString == null)
    {
        return null;
    }

    else
    {
        char ch;
        Regex regex = new Regex(@"[^\u0000-\u007F]", RegexOptions.IgnoreCase);
        Match charMatch = regex.Match(inString);

        for (int i = 0; i < inString.Length; i++)
        {
            ch = inString[i];
            if (char.IsControl(ch))
            {
                string matchedChar = ch.ToString();
                inString = inString.Replace(matchedChar, string.Empty);
            }
        }

        while (charMatch.Success)
        {
            string matchedChar = charMatch.ToString();
            inString = inString.Replace(matchedChar, string.Empty);
            charMatch = charMatch.NextMatch();
        }
    }       

    return inString;
}

我会为那些经验不足的人分解更多细节:

  1. 我们首先遍历整个字符串的每个字符,并使用char的IsControl方法来判断一个字符是否为控制字符。

  2. 如果找到控制字符,将匹配的字符复制到字符串,然后使用 Replace 方法将控制字符更改为空字符串。冲洗并重复其余的字符串。

  3. 一旦我们遍历了整个字符串,我们就使用定义的正则表达式(它将匹配任何不是控制字符或标准 ascii 字符的字符)并再次用空字符串替换匹配的字符。在 while 循环中执行此操作意味着 charMatch 始终为真,该字符将被替换。

  4. 最后,一旦所有字符都被删除并且我们循环了整个字符串,我们就返回了 inString。

(注意:我还没有弄清楚如何用新修改的 inString 值重新填充 TextBox,所以如果有人能指出如何做到这一点,那就太好了)

【讨论】:

  • 你在这里有完全有效的答案,你的解决方案就是基于它们。 \u0000-\u0020 也是控制字符。
最近更新 更多