【问题标题】:Regular expression for all printable characters in JavaScriptJavaScript中所有可打印字符的正则表达式
【发布时间】:2012-08-16 16:16:55
【问题描述】:

寻找一个验证所有可打印字符的正则表达式。正则表达式只需要在 JavaScript 中使用。我浏览过this 的帖子,但它主要讨论的是.net、Java 和C,而不是JavaScript。

您必须只允许这些可打印字符:

az、AZ、0-9 和三十二个符号:!"#$%&'()*+,-./:;?@[] ^_`{|}~ 和空间

需要一个 JavaScript 正则表达式来验证输入字符是上述之一并丢弃其余字符。

【问题讨论】:

标签: javascript regex


【解决方案1】:

TLDR 答案

使用string1.match(/[\p{Cc}\p{Cn}\p{Cs}]+/gu) 作为条件,真正的意思是string1 包含任何不可打印的字符。

或者,如果您想要逻辑等价,string1.match(/^[\P{Cc}\P{Cn}\P{Cs}]+$/gu) 作为条件将在 string1 仅包含可打印字符时返回 true。

TLDR 说明

  • \P{Cc}不要匹配控制字符。
  • \P{Cn}不要匹配未分配的字符。
  • \P{Cs}不要匹配 UTF-8 无效字符。
  • + :确保找到了某些东西,也就是说,这也意味着空字符串 "" 将不被视为可打印。
  • /g : 贪婪匹配,穷举/贪婪地搜索字符串以查找指定的字符集。
  • /u :用于匹配 unicode 字符点的 unicode 正则表达式运算符。 (来源:MDN Web Docs: Regular Expressions; Unicode Property Escapes。)

演示

var string1 = 'This string has unprintable characters \u0001';

if(string1.match(/[\p{Cc}\p{Cn}\p{Cs}]+/gu)) {
  console.log("Unprintable string: " + string1);
}
var string2 = 'This string has only printable characters.';

if(string2.match(/^[\P{Cc}\P{Cn}\P{Cs}]+$/gu)) {
  console.log("Printable string: " + string2);
}

可能的替代方案

  • \P{C} :仅匹配可见字符。不要匹配任何不可见的字符。
  • \P{Cc} :仅匹配非控制字符。不要匹配任何控制字符。
  • \P{Cc}\P{Cn} :仅匹配已分配的非控制字符。不要匹配任何控制或未分配的字符。
  • \P{Cc}\P{Cn}\P{Cs} :仅匹配已分配且 UTF-8 有效的非控制字符。不匹配任何控制、未分配或 UTF-8 无效字符。
  • \P{Cc}\P{Cn}\P{Cs}\P{Cf} :仅匹配已分配且 UTF-8 有效的非控制、非格式字符。不匹配任何控制、未分配、格式化或 UTF-8 无效字符。

来源及说明

查看可用于在正则表达式中进行测试的Unicode Character Properties。您应该能够在Microsoft .NETJavaScriptPythonJavaPHPRubyPerlGolang 甚至Adobe 中使用这些正则表达式。了解 Unicode 字符类是非常容易转移的知识,所以我推荐使用它!

这个正则表达式将匹配任何可见的东西,无论是简写还是长写...

\p{L}\p{M}\p{N}\p{P}\p{S}\p{Z}
\p{Letter}\p{Mark}\p{Number}\p{Punctuation}\p{Symbol}\p{Separator}

\p 表示这是我们想要匹配的东西,但我们也可以选择使用\P(大写)to indicate something that does not match. 所以,这意味着我们可以使用\p{C} 类,用于“隐形控制”字符和未使用的代码点。” (来源:Regular-Expressions.info。)一个更简单的正则表达式是\P{C},但这在删除不可见格式方面可能过于严格。您可能想仔细观察,看看什么是最好的,但其中一种选择应该适合您的需求。

所有可匹配的 Unicode 字符集

如果您想了解任何其他可用的字符集,请查看regular-expressions.info...

  • \p{L}\p{Letter}:来自任何语言的任何类型的信件。
    • \p{Ll}\p{Lowercase_Letter}:带有大写变体的小写字母。
    • \p{Lu}\p{Uppercase_Letter}:带有小写变体的大写字母。
    • \p{Lt}\p{Titlecase_Letter}:当单词的首字母大写时出现在单词开头的字母。
    • \p{L&}\p{Cased_Letter}:以小写和大写形式存在的字母(Ll、Lu 和 Lt 的组合)。
    • \p{Lm}\p{Modifier_Letter}:一个特殊字符,用作字母。
    • \p{Lo}\p{Other_Letter}:不区分大小写的字母或表意文字
  • \p{M}\p{Mark}:旨在与另一个字符组合的字符(例如重音符号、变音符号、封闭框等)。
    • \p{Mn}\p{Non_Spacing_Mark}:一个旨在与另一个字符组合的字符 不占用额外空间的字符(例如重音、变音等)。
    • \p{Mc}\p{Spacing_Combining_Mark}:旨在与占用额外空间的另一个字符组合的字符(许多东方语言中的元音符号)。
    • \p{Me}\p{Enclosing_Mark}:包含与其组合的字符(圆形、方形、键帽等)的字符。
  • \p{Z}\p{Separator}:任何类型的空格或不可见的分隔符。
    • \p{Zs}\p{Space_Separator}:一个不可见但占用空间的空白字符。
    • \p{Zl}\p{Line_Separator}:行分隔符 U+2028。
    • \p{Zp}\p{Paragraph_Separator}:段落分隔符 U+2029。
  • \p{S}\p{Symbol}:数学符号、货币符号、装饰符号、画框字符等。
    • \p{Sm}\p{Math_Symbol}:任何数学符号。
    • \p{Sc}\p{Currency_Symbol}:任何货币符号。
    • \p{Sk}\p{Modifier_Symbol}:一个组合字符(标记)作为一个完整的字符。
    • \p{So}\p{Other_Symbol}:不是数学符号、货币符号或组合字符的各种符号。
  • \p{N}\p{Number}:任何脚本中的任何类型的数字字符。
    • \p{Nd}\p{Decimal_Digit_Number}:除表意文字外的任何文字中的数字 0 到 9。
    • \p{Nl}\p{Letter_Number}:一个看起来像字母的数字,例如罗马数字。
    • \p{No}\p{Other_Number}:上标或下标数字,或不是数字 0-9 的数字(不包括来自表意文字的数字)。
  • \p{P}\p{Punctuation}:任何类型的标点符号。
    • \p{Pd}\p{Dash_Punctuation}:任何类型的连字符或破折号。
    • \p{Ps}\p{Open_Punctuation}:任何类型的左括号。
    • \p{Pe}\p{Close_Punctuation}:任何类型的右括号。
    • \p{Pi}\p{Initial_Punctuation}:任何类型的开场白。
    • \p{Pf}\p{Final_Punctuation}:任何类型的结束语。
    • \p{Pc}\p{Connector_Punctuation}:标点符号,例如连接单词的下划线。
    • \p{Po}\p{Other_Punctuation}:任何非破折号、括号、引号或连接符的标点符号。
  • \p{C}\p{Other}:不可见的控制字符和未使用的代码点。
    • \p{Cc}\p{Control}:ASCII 或 Latin-1 控制字符:0x00–0x1F 和 0x7F–0x9F。
    • \p{Cf}\p{Format}:不可见的格式指示符。
    • \p{Co}\p{Private_Use}:保留供私人使用的任何代码点。
    • \p{Cs}\p{Surrogate}:UTF-16 编码的代理对的一半。
    • \p{Cn}\p{Unassigned}:任何未分配字符的代码点。

【讨论】:

    【解决方案2】:

    对于非 unicode 使用正则表达式模式^[^\x00-\x1F\x80-\x9F]+$


    如果您想使用 unicode,请先阅读 Javascript + Unicode regexes

    我建议然后使用正则表达式模式^[^\p{Cc}\p{Cf}\p{Zl}\p{Zp}]*$

    • \p{Cc}\p{Control}:ASCII 0x00..0x1F 或 Latin-1 0x80..0x9F 控制字符。
    • \p{Cf}\p{Format}:不可见的格式指示符。
    • \p{Zl}\p{Line_Separator}:行分隔符 U+2028。
    • \p{Zp}\p{Paragraph_Separator}:段落分隔符 U+2029。

    欲了解更多信息,请参阅http://www.regular-expressions.info/unicode.html

    【讨论】:

    【解决方案3】:

    要验证字符串仅包含可打印的 ASCII 字符,请使用简单的正则表达式,例如

    /^[ -~]+$/
    

    匹配

    • ^ - 字符串锚的开始
    • [ -~]+ - 一个或多个(由于 + 量词)在 ASCII 表中从空格到波浪号的字符:


    - $ - 字符串锚点结束

    对于 Unicode 可打印字符,使用 XRegExp 中的 \PC Unicode 类别(匹配除控制字符以外的任何字符),如前所述:

    ^\PC+$
    

    查看正则表达式演示:

    // ASCII only
    var ascii_print_rx = /^[ -~]+$/;
    console.log(ascii_print_rx.test("It's all right.")); // true
    console.log(ascii_print_rx.test('\f ')); // false, \f is an ASCII form feed char
    console.log(ascii_print_rx.test("demásiado tarde")); // false, no Unicode printable char support
    // Unicode support
    console.log(XRegExp.test('demásiado tarde', XRegExp("^\\PC+$"))); // true
    console.log(XRegExp.test('‌ ', XRegExp("^\\PC+$"))); // false, \u200C is a Unicode zero-width joiner
    console.log(XRegExp.test('\f ', XRegExp("^\\PC+$"))); // false, \f is an ASCII form feed char
    <script src="http://cdnjs.cloudflare.com/ajax/libs/xregexp/3.1.1/xregexp-all.min.js"></script>

    【讨论】:

    • 第一个选项很巧妙(除非我们需要 Unicode)。
    【解决方案4】:

    自发布此问题以来,JavaScript 似乎发生了某种程度的变化?

    我正在使用这个:

    var regex = /^[\u0020-\u007e\u00a0-\u00ff]*$/;
    console.log( regex.test("!\"#$%&'()*+,-./:;<=>?@[] ^_`{|}~")); //should output "true" 
    console.log( regex.test("Iñtërnâtiônàlizætiøn")); //should output "true"
    console.log( regex.test("☃?")); //should output "false" 
    

    【讨论】:

    • 我觉得应该是\x20-\x7e\x80-\xff
    【解决方案5】:

    如果您想匹配 UTF-8 集中的所有可打印字符(如您在 8 月 21 日的评论所示),您自己将很难做到这一点。 JavaScript 的原生正则表达式具有糟糕的 Unicode 支持。但是您可以将XRegExp 与正则表达式^\P{C}*$ 一起使用。

    如果您只想将编辑中提到的那几个 ASCII 字母与 8 月 22 日的帖子相匹配,那么正则表达式是微不足道的:

    /^[a-z0-9!"#$%&'()*+,.\/:;<=>?@\[\] ^_`{|}~-]*$/i
    

    【讨论】:

    • 我想这是一个很好的解决方案,但假设我只想要 UTF-8 的可打印字符,你能在不使用任何第三方 JavaScript 库的情况下给我一个正则表达式吗?
    • @AurA:XRegExp 编译为原生 JavaScript。
    • 我已经知道了,但是我有这个限制……我不能使用第三方库。这就是为什么我只要求使用 UTF-8,这将大大减少字符数量并且可以使用正则表达式处理。
    • UTF-8 具有与 UTF-16 和 UTF-32 相同的字符数完全。 UTF-8 只是一种编码 - 它具有所有 unicode - 整个事物。你是说ASCII吗?
    • en.wikipedia.org/wiki/UTF-8 在这些给定的字符中,我想检查输入的字符串是否有任何不可打印的字符,或者在按键上我想检查输入的字符是否可打印。
    猜你喜欢
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    相关资源
    最近更新 更多