JS Regex允许不正确的字符

时间:2015-09-23 12:50:31

标签: javascript regex

我有SEPA付款的评论字段,这样的字段在用户可以输入的内容方面有以下限制:

a b c d e f g h i j k l m n o p q r s t u v w x y z
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9
/ – ? : ( ) . , ‘ +
Space

所以我有这个功能,只是在不允许时阻止用户输入:

    $('.no_special_chars').keypress(function (e) {          
        var regex = new RegExp("^[a-zA-Z0-9\/\-\?\:\(\)\.\,\'\+\\s]+?$");
        console.log(String.fromCharCode(!e.charCode ? e.which : e.charCode));
        var str = String.fromCharCode(!e.charCode ? e.which : e.charCode);

        // Allow tab, left/right arrow, backspace and delete. Then proceed to validation
        if (e.keyCode == 9 || e.keyCode == 37 || e.keyCode == 39 || e.keyCode == 8 || e.keyCode == 46) {
            return true;
        }

        // Do not allow returns in the comment field
        if (e.keyCode == 13) {
            return false;
        }

        if (regex.test(str)) {
            return true;
        }

        return false;
    });

但是,我注意到Chrome例如也允许使用以下字符:     %     =     <     > Firefox也接受所有这些,减去%。

我做错了什么以及为什么这些浏览器会有不同的反应?

2 个答案:

答案 0 :(得分:2)

问题是由于您通过RegExp构造函数声明正则表达式的方式。连字符应该被转义两次,以便在那里被视为字面连字符。

这是它允许的范围:

enter image description here

建议在从一开始就知道正则表达式时使用文字表示法,最佳做法是在字符类范围的末尾使用连字符,以避免将其转义。

要匹配范围内的0个或更多字符,您需要使用

var regex = /^[a-z0-9\/?:().,\'+\s-]*$/i;

请参阅此demo fiddle

如果您计划至少匹配1个(或更多),请保持+?(或+,它在您的情况下的工作方式相同)量词。

$('.no_special_chars').keypress(function (e) {   
  var regex = /^[a-z0-9\/?:().,\'+\s-]*$/i;
  console.log(String.fromCharCode(!e.charCode ? e.which : e.charCode));
  var str = String.fromCharCode(!e.charCode ? e.which : e.charCode);

  // Allow tab, left/right arrow, backspace and delete. Then proceed to validation
  if (e.keyCode == 9 || e.keyCode == 37 || e.keyCode == 39 || e.keyCode == 8 || e.keyCode == 46) {
     return true;
  }

  // Do not allow returns in the comment field
  if (e.keyCode == 13) {
     return false;
  }

  if (regex.test(str)) {
     return true;
  }

  return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="no_special_chars">
<input type="text" class="form-control" id="id_number" name="id_number" maxlength="20" required>
</div>

答案 1 :(得分:1)

这里有几个问题在起作用。转义后,您的实际字符串如下(您可以使用console.log(regex);确认)

/^[a-zA-Z0-9\/-?:().,'+\s]+?$/

请注意,/-?实际上是有效范围!其中包括密钥代码/(47)到?(63)中的字符,其中包含/0123456789:;<=>?。你需要逃避连字符-,但因为你在一个也有逃避规则的字符串里面工作,你需要逃避逃脱者&#34;使用双\\,如下所示:

"^[a-zA-Z0-9/\\-?:().,'+]+?$"
             ^^ string-escaped \

其次,您对keyCode = 37的检查是允许Chrome中%的内容。在Chrome中,即使您完全删除了部分代码,仍然允许使用箭头键,退格键等,因此您甚至不需要检查这些键码。但是,在FireFox中,代码按预期工作。