首页 > 解决方案 > 为什么正则表达式在javascript中有时不起作用?

问题描述

您好我正在使用正则表达式来验证输入,这个想法是用户不能基于正则表达式键入一些字符。我用 2 个正则表达式进行了测试,但 te first 不起作用。即使我在该页面上进行测试:https ://regexr.com/ 两者都可以正常工作,但在代码中却不行。你能帮帮我吗?谢谢。

我需要一个让我输入 0 到 180 范围的正则表达式

期望的行为:

在此处输入图像描述

在此处输入图像描述

function regex1(str) {
  
  var splitStr = str.split("");
  
  var filterArray = splitStr.filter(function(val) {
    
    // Test the string against the regular expression
    // and test for no match (whole thing is preceeded by !)
    return !/^([0-9]|[1-9][0-9]|1[0-7][0-9]|180)$/g.test(val);
  });
  
  return filterArray;
}

function regex2(str) {
  
  var splitStr = str.split("");
  
  var filterArray = splitStr.filter(function(val) {
    
    // Test the string against the regular expression
    // and test for no match (whole thing is preceeded by !)
    return !/[^1-3]+/g.test(val);
  });
  
  return filterArray;
}

console.log(regex1("180"));
console.log(regex2("3"));

标签: javascriptregexvue.js

解决方案


您的问题在于两个方面:

  1. 您的var splitStr = str.split("");行将字符串拆分为单个字符,这意味着您永远不会测试“180”,而是分别测试“1”、“8”和“0”
  2. 正则表达式是验证数值范围的糟糕工具

真的应该重新考虑为此目的使用正则表达式,而是应该将输入解析为数字并对其进行测试,除非有其他原因需要这样做。改为解析和测试的一个原因是,可能存在您的表达式未涵盖的边缘情况,即使它们可能是有效的。

如果由于某种原因,您绝对必须使用正则表达式,则需要测试整个字符串,而不是逐个字符地测试,只需使用与您相同的RegExp.prototype.test()函数即可:

function regex1(str) {
    return /^([0-9]|[1-9][0-9]|1[0-7][0-9]|180)$/g.test(str);
}

var tests = ['0', '1', '120', '180', '181'];
for (var str of tests)
  console.log(`${str}:`, regex1(str));

作为替代解决方案的示例:
如果您使用 HTML<input>进行表单输入,那么它们已经具有设置最大(和最小)数字输入的机制。尝试使用无效输入提交将阻止表单提交:

<form>
  <input type="number" max="180" placeholder="0 - 180">
  <input type="Submit">
</form>


推荐阅读