【问题标题】:Remove zero-width space characters from a JavaScript string从 JavaScript 字符串中删除零宽度空格字符
【发布时间】:2012-07-03 13:59:33
【问题描述】:

我接受用户输入(JS 代码)并实时执行(处理)它们以显示一些输出。

有时代码有那些零宽度的空格;这真的很奇怪。我不知道用户是如何输入的。示例:"(​$".length === 3

我需要能够从我的 JS 代码中删除该字符。我该怎么做?或者也许还有其他方法可以执行该 JS 代码,以便浏览器不考虑零宽度空格字符?

【问题讨论】:

  • 你是如何推断出有一个零宽度字符的?单从长度?非 BMP 字符的长度为 2。
  • 当我走到字符串的末尾并按左箭头时,有一次,它不会向左移动,直到按两次左箭头键。我就是这么推断的。
  • 然后你需要分析字符,例如通过写出数字代码。数据可能包含组合标记,以便在向左移动时将两个或多个字符视为一个单元。

标签: javascript unicode


【解决方案1】:
[].filter.call( str, function( c ) {
    return c.charCodeAt( 0 ) !== 8203;
} );

过滤每个字符以去除 8203 字符代码(零宽度空格 unicode 数字)。

【讨论】:

  • 这是一个聪明的解决方案,使用现代 JavaScript 可以将其简化为单行:[].filter.call(strVal, c => c.charCodeAt() !== 8203).join('')
【解决方案2】:

Unicode 具有以下零宽度字符:

  • U+200B 零宽度空间
  • U+200C 零宽度非连接 Unicode 代码点
  • U+200D 零宽度连接符 Unicode 代码点
  • U+FEFF 零宽度不间断空格 Unicode 代码点

要从 JavaScript 中的字符串中删除它们,您可以使用简单的正则表达式:

var userInput = 'a\u200Bb\u200Cc\u200Dd\uFEFFe';
console.log(userInput.length); // 9
var result = userInput.replace(/[\u200B-\u200D\uFEFF]/g, '');
console.log(result.length); // 5

请注意,还有更多符号可能不可见。一些ASCII’s control characters,例如。

【讨论】:

  • @Iván Castellanos mentioned 可以考虑的其他一些字符:U+200E LEFT-TO-RIGHT MARK 和 U+200F RIGHT-TO-LEFT MARK。就像我说的,可能还有其他符号,它们本身并不是严格可见的。
  • 我们如何在DOM加载后检测这些值是否真的存在于页面上?谢谢!
  • var HTMLe=document.getElementsByTagName('html')[0]; HTMLe.outerHTML = HTMLe.outerHTML.replace(/[\u200B-\u200D\uFEFF\u200E\u200F]/g, ''); ...就是这样
  • 如果字符串是一串 unicode 字符,这将不起作用 - 仅使用它们创建一个 var 就会出错 var s = "\ud83d\ude0d\ud83d\ude0d\ud83d\ude0d\ud83d\ude0d\ud83d\ude0d‌​\ud83d\ude0d\ud83d\u‌​de0d\ud83d\ude0d\ud8‌​3d\ude0d\ud83d\ude18‌​\ud83d\ude18\ud83d\u‌​de18"
【解决方案3】:

我遇到了一个问题,一些不可见的字符正在破坏我的 JSON,并导致 Unexpected Token ILLEGAL 异常导致我的网站崩溃。

这是我使用 RegExp 变量的解决方案:

    var re = new RegExp("\u2028|\u2029");
    var result = text.replace(re, '');

您可以在此处找到有关 Javascript 和零宽度空格的更多信息: Zero Width Spaces

【讨论】:

  • or 符号可能会更慢(在 IE 中),因为它针对多字符匹配进行了优化。但是,使用 google 的 V8,谁知道呢,它可能运行得一样快。
  • 这些不可见的零宽度 unicode 字符可用于为那些敢于通过浏览器复制并粘贴到另一个知道接收消息并将零宽度元数据转换回的编辑器的用户隐藏元数据凭据字符的缺失。因此,您复制并粘贴单词“hi”,然后传输的是h,然后是元数据凭据字符串,然后是i。但是源和目标只显示单词hi。要将这些零宽度的野蛮人和他们的波斯信使留在斯巴达的护城河将是一场斗争。伤心!
【解决方案4】:
str.replace(/\u200B/g,'');

200B 是零宽度空间 8203 的十六进制。用空字符串替换它以删除它

【讨论】:

    【解决方案5】:

    如果您尝试在 JavaScript 中执行此操作,请尝试 this regex

    /([\u200B]+|[\u200C]+|[\u200D]+|[\u200E]+|[\u200F]+|[\uFEFF]+)/g
    

    submit.onclick = evt => {
      const stringToTrim = stringValue.value;
      zeroWidthTrim(stringToTrim);
    }
    
    /**
     * Given a string, when it has zero-width spaces in it, then remove them
     *
     * @param {String} stringToTrim The string to be trimmed of unicode spaces
     *
     * @return the trimmed string
     *
     * Regex for zero-width space Unicode characters.
     *
     * U+200B zero-width space.
     * U+200C zero-width non-joiner.
     * U+200D zero-width joiner.
     * U+200E left-to-right mark.
     * U+200F right-to-left mark.
     * U+FEFF zero-width non-breaking space.
     */
    function zeroWidthTrim(stringToTrim) {
      const ZERO_WIDTH_SPACES_REGEX = /([\u200B]+|[\u200C]+|[\u200D]+|[\u200E]+|[\u200F]+|[\uFEFF]+)/g;
      console.log('stringToTrim = ' + stringToTrim);
      const trimmedString = stringToTrim.replace(ZERO_WIDTH_SPACES_REGEX, '');
      console.log('trimmedString = ' + trimmedString);
      return trimmedString;
    };
    <form runat="server">
      <input name="stringValue" id="stringValue" type="text" placeholder="enter your string" value="[&#x200b;&#x200c;]" />
      <input type="button" value="remove zero-width characters" id="submit" />
    </form>

    (运行上述代码 sn-p 后,将 stringToTrim 值和 trimmedString 值粘贴到 regex101 test window 中,您将看到 Unicode 字符已从 trimmedString 值中消失。)

    【讨论】:

      猜你喜欢
      • 2018-02-19
      • 2014-08-04
      • 1970-01-01
      • 1970-01-01
      • 2014-07-04
      • 2014-02-12
      • 1970-01-01
      • 2011-09-21
      相关资源
      最近更新 更多