JavaScript中所有可打印字符的正则表达式

18

寻找一个正则表达式来验证所有可打印字符。这个正则表达式需要仅在JavaScript中使用。我已经查阅了这篇文章,但它主要讨论了.net、Java和C,而不是JavaScript。

你需要允许以下可打印字符:

a-z、A-Z、0-9和32个符号:!"#$%&'()*+,-./:;<=>?@[] ^_`{|}~ 以及空格

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


全部?你确定吗?你知道有多少个Unicode字符吗? - Ariel
3
很不幸,JavaScript 不支持 Unicode 字符类:https://dev59.com/AnVC5IYBdhLWcg3weBE- - Ariel
Unicode UTF-16应该有2^16个字符。 - AurA
1
@AurA:差得远呢。在进一步深入此事之前,你绝对需要阅读Joel的Unicode文章 - Tim Pietzcker
5个回答

17

如果你想要匹配UTF-8字符集中的所有可打印字符(根据你在8月21日的评论所示),自己做可能会很困难。JavaScript的原生正则表达式对Unicode支持不佳,但你可以使用XRegExp和正则表达式^\P{C}*$

如果你只想匹配从8月22日的帖子编辑中提到的那几个ASCII字母,则正则表达式很简单:

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

我猜那是一个不错的解决方案,但是假设我只想要UTF-8可打印字符,你能否给我一个正则表达式而不使用任何第三方JavaScript库。 - AurA
@AurA:XRegExp编译成本地JavaScript。 - Tim Pietzcker
1
我已经知道了,但是我在这里有限制...我不能使用第三方库。这就是为什么我只要求UTF-8,这将大大减少字符数量,并且可以用正则表达式处理。 - AurA
5
UTF-8与UTF-16、UTF-32的字符数量完全相同。UTF-8只是一种编码方式,包含了Unicode的全部内容。您是指ASCII吗? - Ariel
从这些给定的字符中,我想检查输入的字符串是否有任何不可打印的字符,或者在按键时我想检查输入的字符是否可打印。http://en.wikipedia.org/wiki/UTF-8 - AurA

13

对于非 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


你可以使用 https://github.com/mathiasbynens/regexpu-core 将它转译成ES5。 - avetisk

13

要验证一个字符串是否只包含可打印的ASCII字符,可以使用简单的正则表达式,例如

/^[ -~]+$/

它匹配

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

enter image description here
- $ - 字符串结尾锚点

对于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>


6
第一个选项很巧妙(除非我们需要Unicode)。 - dan

11
自从这个问题被发布以来,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 - Vitim.us

7

简短回答

使用 string1.match(/[\p{Cc}\p{Cn}\p{Cs}]+/gu) 作为条件语句,如果返回true,则表示string1 包含任何不可打印字符。

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

简短解释

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

Demo

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字符属性。您应该能够在Microsoft .NET, JavaScript, Python, Java, PHP, Ruby, Perl, Golang甚至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(大写) 表示不匹配的内容 的选项。这意味着我们可以使用 \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}:旨在与另一个字符组合的字符(例如重音符号、umlauts、包围框等)。
    • \p{Mn}\p{Non_Spacing_Mark}:旨在与另一个字符组合而不占用额外空间的字符(例如重音符号、umlauts等)。
    • \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}:任何脚本中的任何类型的数字字符。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接