在Javascript中进行字母数字检查的最佳方式

t0m*_*cat 95 javascript validation

您能否建议在JSP中对INPUT字段执行字母数字检查的最佳方法?我已附上我当前的代码,我知道它没有接近完美:)

<script type="text/javascript">
  function validateCode(){
      var TCode = document.getElementById('TCode').value;
      for(var i=0; i<TCode.length; i++)
      {
        var char1 = TCode.charAt(i);
        var cc = char1.charCodeAt(0);

        if((cc>47 && cc<58) || (cc>64 && cc<91) || (cc>96 && cc<123))
        {

        }
         else {
         alert('Input is not alphanumeric');
         return false;
         }
      }
     return true;     
   }
Run Code Online (Sandbox Code Playgroud)

Mah*_*aga 89

你可以使用这个正则表达式 /^[a-z0-9]+$/i

  • `ñ`不属于模式,但完全有效的UTF-8字符. (13认同)
  • / ^ [a-z0-9] + $/i.test(TCode) (8认同)
  • 当然这假设不应该匹配空字符串("""). (4认同)
  • 测试正则表达式似乎比`charCodeAt()`慢得多(在Chrome 36中为66%).请参阅[jsPerf](http://jsperf.com/alphanumeric-charcode-vs-regexp)和[我的答案如下](http://stackoverflow.com/a/25352300/388639). (3认同)
  • 此正则表达式不适用于某些语言中使用的特殊字符字母,例如“±”,“ź”,“ć”等。 (3认同)
  • 这排名怎么这么高? (2认同)

Mic*_*ker 70

提问者最初使用的倾向str.charCodeAt(i)似乎比正则表达式更快.在我对jsPerf测试中, RegExp选项在Chrome 36中的执行速度降低了66%(在Firefox 31中略慢).

这是原始验证代码的清理版本,它接收字符串并返回truefalse:

function isAlphaNumeric(str) {
  var code, i, len;

  for (i = 0, len = str.length; i < len; i++) {
    code = str.charCodeAt(i);
    if (!(code > 47 && code < 58) && // numeric (0-9)
        !(code > 64 && code < 91) && // upper alpha (A-Z)
        !(code > 96 && code < 123)) { // lower alpha (a-z)
      return false;
    }
  }
  return true;
};
Run Code Online (Sandbox Code Playgroud)

当然,可能还有其他考虑因素,例如可读性.单行正则表达式看起来绝对更漂亮.但如果您严格关注速度,可能需要考虑这种替代方案.

  • 程序员喜欢代码的外观,但你看到它的内在美. (15认同)
  • 为什么我们需要在 charCode `charCodeAt` 中进行比较?难道我们不能只与字符串 char `(c &gt;= '0' &amp;&amp; c &lt;= '9')`, `(c &gt;= 'a' &amp;&amp; c &lt;= 'z')`, `( c &gt;= 'A' &amp;&amp; c &lt;= 'Z')`? (6认同)

Mis*_*iev 36

用正则表达式检查它.

Javascript regexen没有POSIX字符类,因此您必须手动编写字符范围:

if (!input_string.match(/^[0-9a-z]+$/))
  show_error_or_something()
Run Code Online (Sandbox Code Playgroud)

^意味着字符串的开头和$手段字符串的结尾,而[0-9a-z]+意味着一个或更多从性格09或从az.

有关Javascript regexen的更多信息,请访问:https: //developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions

  • +1用于解释基本正则表达式并链接到指南,而不是给用户一个"魔术字符串". (12认同)
  • 你需要添加AZ (5认同)
  • @inor您可以在正则表达式的末尾添加“ i”以指定不区分大小写,即`/ ^ [a-z0-9] + $ / i`,这将覆盖大小写字母 (4认同)

use*_*716 33

您不需要一次只执行一个.只需对任何字母数字进行测试.如果找到一个,则验证失败.

function validateCode(){
    var TCode = document.getElementById('TCode').value;
    if( /[^a-zA-Z0-9]/.test( TCode ) ) {
       alert('Input is not alphanumeric');
       return false;
    }
    return true;     
 }
Run Code Online (Sandbox Code Playgroud)

如果至少有一个非字母数字的匹配,它将return false.


3li*_*t0r 9

要匹配所有 Unicode 字母和数字,您可以使用 Unicode 正则表达式:

const alphanumeric = /^[\p{L}\p{N}]+$/u;

const valid   = "Jòhn?Çoe???3rd"; // <- these are all letters or numbers
const invalid = "JohnDoe3rd!";

console.log(valid.match(alphanumeric));
console.log(invalid.match(alphanumeric));
Run Code Online (Sandbox Code Playgroud)

在上面的正则表达式中,u标志启用Unicode 模式\p{L}是短期的\p{Letter}\p{N}短暂的\p{Number}[]它们周围的方括号是一个普通的字符类,这意味着字符必须是字母或数字(在这种情况下)。该+是“一个或多个”,你可以改变这个*(零个或多个),如果你也想允许空字符串。^/$匹配字符串的开始/结束。


以上内容足以满足大多数情况,但可能比您想要的更多。您可能不想匹配拉丁文、阿拉伯文、西里尔文等。您可能只想匹配拉丁字母和十进制数字。

const alphanumeric = /^[\p{sc=Latn}\p{Nd}]+$/u;

const valid   = "JòhnÇoe3rd";
const invalid = "Jòhn?Çoe???3rd";

console.log(valid.match(alphanumeric));
console.log(invalid.match(alphanumeric));
Run Code Online (Sandbox Code Playgroud)

\p{sc=Latn}是 的缩写\p{Script=Latin}\p{Nd}\p{Decimal_Number}小数的缩写并匹配小数。与 的不同之\d处在于\p{Nd}不仅匹配5,而且还匹配?并且可能更多。

查看正则表达式 Unicode 文档以获取详细信息,可用\p选项链接在文档页面上。


Osc*_*rus 7

这里有一些注意事项: 真正的字母数字字符串是 like"0a0a0a0b0c0d"和 not like"000000""qwertyuio"

我在这里读到的所有答案,true在这两种情况下都返回了。这是不对的

如果我想检查我的"00000"字符串是否是字母数字,我的直觉无疑是错误的。

为什么?简单的。我找不到任何字母字符。所以,是一个简单的数字字符串[0-9]

另一方面,如果我想检查我的"abcdefg"字符串,我的直觉仍然是错误的。我没有看到数字,所以它不是字母数字。只是阿尔法[a-zA-Z]

迈克尔·马丁-斯马克的答案已经被照亮。

然而,他的目标是实现更好的性能而不是正则表达式。这是真的,使用低级别的方式有更好的性能。但结果是一样的。字符串"0123456789"(仅数字)、"qwertyuiop"(仅字母)和"0a1b2c3d4f4g"(字母数字)TRUE作为字母数字返回。相同的正则表达式/^[a-z0-9]+$/i方式。正则表达式不起作用的原因很简单。语法[]指示or, not and。因此,如果它只是数字只是字母,则正则表达式返回true.

但是,Michael Martin-Smucker 的回答仍然很有启发性。为了我。它让我能够在“低级”思考,创建一个明确处理字母数字字符串的真实函数。我称它为 PHP 相关函数ctype_alnum编辑 2020-02-18:然而,这里检查 OR 而不是 AND)。

这是代码:


function ctype_alnum(str) {
  var code, i, len;
  var isNumeric = false, isAlpha = false; // I assume that it is all non-alphanumeric

  for (i = 0, len = str.length; i < len; i++) {
    code = str.charCodeAt(i);

    switch (true) {
      case code > 47 && code < 58: // check if 0-9
        isNumeric = true;
        break;

      case (code > 64 && code < 91) || (code > 96 && code < 123): // check if A-Z or a-z
        isAlpha = true;
        break;

      default:
        // not 0-9, not A-Z or a-z
        return false; // stop function with false result, no more checks
    }
  }

  return isNumeric && isAlpha; // return the loop results, if both are true, the string is certainly alphanumeric
}

Run Code Online (Sandbox Code Playgroud)

这是一个演示:

function ctype_alnum(str) {
  var code, i, len;
    var isNumeric = false, isAlpha = false; //I assume that it is all non-alphanumeric

    
loop1:
  for (i = 0, len = str.length; i < len; i++) {
    code = str.charCodeAt(i);
        
        
        switch (true){
            case code > 47 && code < 58: // check if 0-9
                isNumeric = true;
                break;
            case (code > 64 && code < 91) || (code > 96 && code < 123): //check if A-Z or a-z
                isAlpha = true;
                break;
            default: // not 0-9, not A-Z or a-z
                return false; //stop function with false result, no more checks
                
        }

  }
    
  return isNumeric && isAlpha; //return the loop results, if both are true, the string is certainly alphanumeric
};

$("#input").on("keyup", function(){

if ($(this).val().length === 0) {$("#results").html(""); return false};
var isAlphaNumeric = ctype_alnum ($(this).val());
    $("#results").html(
        (isAlphaNumeric) ? 'Yes' : 'No'
        )
        
})
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="input">

<div> is Alphanumeric? 
<span id="results"></span>
</div>
Run Code Online (Sandbox Code Playgroud)

这是Michael Martin-Smucker 方法在 JavaScript 中的实现。

  • 上面解决的是 alphaAndNumeric,而不是 alphaNumeric。`返回值为数字|| isAlpha;` 是字母数字。以上内容可能对某些人有帮助。 (2认同)

Jus*_*tin 6

我会创建一个String原型方法:

String.prototype.isAlphaNumeric = function() {
  var regExp = /^[A-Za-z0-9]+$/;
  return (this.match(regExp));
};
Run Code Online (Sandbox Code Playgroud)

然后,用法将是:

var TCode = document.getElementById('TCode').value;
return TCode.isAlphaNumeric()
Run Code Online (Sandbox Code Playgroud)

  • [可维护的JavaScript:不要修改您不拥有的对象](http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/ ) (3认同)
  • DJDavid98:我不认为规则"不修改你不拥有的对象"适用于此处.Justin只是扩展了String的功能,而不是修改现有的功能.对于透视图,在C#world中,这将被视为扩展方法的完全有效用法.即使有一天"String.isAlphaNumeric():boolean"将由浏览器制造商实现,签名和动作都不会实际改变,所以在这个特定的例子中我看不到任何可维护性的降低.这个规则并不意味着没有例外. (2认同)

Nee*_*jan 5

    // On keypress event call the following method
    function AlphaNumCheck(e) {
        var charCode = (e.which) ? e.which : e.keyCode;
        if (charCode == 8) return true;

        var keynum;
        var keychar;
        var charcheck = /[a-zA-Z0-9]/;
        if (window.event) // IE
        {
            keynum = e.keyCode;
        }
        else {
            if (e.which) // Netscape/Firefox/Opera
            {
                keynum = e.which;
            }
            else return true;
        }

        keychar = String.fromCharCode(keynum);
        return charcheck.test(keychar);
    }
Run Code Online (Sandbox Code Playgroud)

此外,本文还有助于理解JavaScript字母数字验证.


Mal*_*nis 5

在一个紧凑的循环中,最好避免使用正则表达式并对字符进行硬编码:

const CHARS = new Set("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
function isAlphanumeric(char) {
    return CHARS.has(char);
}
Run Code Online (Sandbox Code Playgroud)

  • 当在循环中扫描整个字符串时,此代码的复杂度为 O(N^2),并且会导致比所提供的最差正则表达式解决方案更差的性能(例如,用户传递所有“Z”,indexOf() 必须扫描到每个字符结束)。它不仅可能会产生扫描整个 0-Z 字符串的开销(平均每次调用执行 18 个字符比较),而且还会产生相当于源字符串每个字符的两次函数调用的开销 - 这是一个相当重要的常数时间值!该代码甚至可能引入 DoS 漏洞,具体取决于其使用位置。 (2认同)