【问题标题】:Allow arrow keys in Regular Expression允许在正则表达式中使用箭头键
【发布时间】:2015-04-14 12:36:50
【问题描述】:

我正在执行字母数字验证,现在我正在这样做,用户只能输入字母数字值,并且仅在粘贴时允许字母数字值。所以我使用了下面的正则表达式

function OnlyAlphaNumeric(evt) {
var charCode = (evt.which) ? evt.which : event.keyCode;
if ((charCode > 32 && charCode < 48) || (charCode > 57 && charCode < 65) ||    
                    (charCode > 90 && charCode < 97) || charCode > 122) {
    return false;
}
else {
    return true;
   }
}

为了防止复制和粘贴,

function CPOnlyAlphaNumeric(evt) {

     $(evt).val($(evt).val().replace(/[^A-Za-z0-9]/g, ' '))

}

这两个函数是从下面的 onkeypress 和 onkeyup 方法调用的,如下所示

   @Html.TextBoxFor(model => model.ProductName, new { @class = "form-  
       control", @onkeypress = "return OnlyAlphaNumeric(this);", @onkeyup=   
        "return CPOnlyAlphaNumeric(this);" })

这适用于字母数字验证,但不允许光标向左移动以编辑文本。那么我应该在我的正则表达式中做些什么改变。

【问题讨论】:

    标签: javascript jquery regex razor onkeyup


    【解决方案1】:

    您的问题与正则表达式无关。

    当您按下任意键(包括左/右箭头)时,您获取输入值,替换所有禁用字符并设置输入值。当最后一个动作完成时,将光标移动到输入的末尾是浏览器的本机行为。

    您可以检查按下的键是什么以及是否是左/右箭头以跳过对输入值的操作。

    function CPOnlyAlphaNumeric(evt) { 
        var code = evt.which ? evt.which : event.keyCode;
    
        // 37 = left arrow, 39 = right arrow.
        if(code !== 37 && code !== 39)
            $(evt).val($(evt).val().replace(/[^A-Za-z0-9]/g, ' '))
    }
    

    Demo

    但这不是一个好的解决方案,因为它会导致可怕的行为(您将无法使用 shift 进行标记,光标将在单词中间第一个键入字母后移动到末尾等。 .)

    更好的解决方案可能是“清理”输入值,比如在用户停止输入后 500 毫秒。

    var timeout = null;
    
    function CPOnlyAlphaNumeric(evt) {
        if(timeout)
            clearTimeout(timeout);
    
        timeout = setTimeout(function(){ 
            $(evt).val($(evt).val().replace(/[^A-Za-z0-9]/g, ' '))
        }, 500);
    }
    

    Demo

    请注意,您还需要在服务器端添加验证(可能在表单提交之前,因为用户可以在触发“清理”输入之前按 Enter 提交表单)。

    【讨论】:

    • 我可以在没有'setTimeout'函数的情况下编写这段代码吗?有没有可能?
    • 如果我复制并粘贴任何文本,那么“替换”也需要 500 毫秒。所以我不想使用“setTimeout”功能。如果您知道其他解决方案@Viktor Bahtev,请帮助我
    • 第一个解决方案不使用“setTimeout”,但正如我所说,它会导致可怕的行为。我建议使用带有“setTimeout”的解决方案。如果您不希望 'setTimeout' 仅用于粘贴文本,您可以使用两个函数 - 一个使用 setTimeout 处理 keyupkeydowninput 事件,另一个不使用 setTimeout 处理 paste 事件。跨度>
    • 我尝试了很多方法,但我找不到解决方案,所以请帮助我。能给个示例代码吗?
    • 我试过了,但是打字后光标移动到了结尾@Viktor Bahtev
    【解决方案2】:

    你可以试试这个,它可能会解决你的问题。

      var regex = new RegExp("^[a-zA-Z0-9]+$");
    
      var charCode =(typeof event.which == "number") ?event.which:event.keyCode
    
      var key = String.fromCharCode(charCode);
    
      if (!(charCode == 8 || charCode == 0)) {
    
          if (!regex.test(key)) {
                event.preventDefault();
                return false;
            }
        }
    

    【讨论】:

      【解决方案3】:

      keyDown 事件的问题是您不能禁止在文本字段中显示键(在我的情况下只有字母数字)。您只能在 keyPress 事件中执行此操作。但是您无法在 keyPress 事件中获取导航键,您只能在 KeyDown 事件中跟踪它们。并且某些键 $,% 具有与箭头键在 keypress 事件中相同的 e.which。这导致我编写逻辑以允许箭头键但将文本限制为仅字母数字。这是我想出的代码。现在工作正常。

          onKeyPress: function(e){
                  var regex = new RegExp("^[a-zA-Z0-9\b ]+$");
                  var str = String.fromCharCode(!e.charCode ? e.which : e.charCode);
                  var allowedSpecialKeys = 'ArrowLeftArrowRightArrowUpArrowDownDelete';
                  var key = e.key;
      
                  /*IE doesn't fire events for arrow keys, Firefox does*/
                  if(allowedSpecialKeys.indexOf(key)>-1){
                      return true;
                  }
      
                  if (regex.test(str)) {
                      return true;
                  }
      
                  e.preventDefault();
                  e.stopPropagation();
                  e.cancelBubble = true;
                  return false;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多