【问题标题】:Javascript Regex validator for specific condition特定条件的 Javascript 正则表达式验证器
【发布时间】:2015-06-01 04:43:33
【问题描述】:

我需要一个可以完全满足以下条件的 javascript 正则表达式验证器。

  1. 字符串应仅包含字母和空格。
  2. 第一个字符必须是字母(小写或大写)。
  3. 空格是允许的,但不是强制性的。
  4. 不应重复空格。但是字符串中可以有多个空格。
  5. 最后一个字符必须是字母(小写或大写)。

提前致谢。

【问题讨论】:

  • 简单的正则表达式。你试过什么?
  • 我试过 - “/^[a-zA-Z]+[a-zA-Z\s]+[a-zA-Z]$/”。但它不起作用@Michael

标签: javascript regex validation


【解决方案1】:

由于现有答案存在灾难性的回溯问题,或者过于复杂,这里有一个更简单的解决方案:

/^[a-zA-Z]+(?: [a-zA-Z]+)*$/.test(input)

我将\s 更改为一个简单的空格,因为\s 匹配空格、制表符、换行符以及其他字符。

附录

Leo's answer at revision 2 有灾难性的回溯问题:

/^(?:[a-zA-Z]+\s?)*[a-zA-Z]$/

您可以尝试使用简单的失败字符串。例如:

/^(?:[a-zA-Z]+\s?)*[a-zA-Z]$/.test("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8")

问题是由于可选的\s,导致(?:[a-zA-Z]+\s?)*退化为(?:[a-zA-Z]+)*,这是经典的灾难性回溯模式(A*)*

【讨论】:

  • 感谢您的提示。从性能的角度来看,我当前的答案和你的答案有区别吗(除了\s 的事情,我把决定留给 OP)?还有其他方法,比如/^(?:[a-z]+\s)*[a-z]+$/i,我觉得会慢一点,是吗?
  • @Leo: token (sep token)* 表单在匹配情况下比(token sep)* token 产生更少的回溯。对于最后一个token,它总是进入(token sep),匹配token但不能匹配sep,然后它必须回溯并重新匹配token,所以它更慢(但它没有灾难性那么重要回溯,并且在大多数情况下可能无法观察到)。不过,我仍然建议使用token (sep token)*,因为它可能会在不损失清晰度的情况下获得收益。
【解决方案2】:

你可以试试这个:

var re = /^(?:[a-zA-Z]+\s)*[a-zA-Z]+$/

re.test('a')     // true
re.test('ab')    // true
re.test('a b')   // true
re.test('a b c') // true
re.test('a  b')  // false
re.test('ab ')   // false
re.test(' ab')   // false
re.test('ab1')   // false

【讨论】:

  • 灾难性回溯:/^(?:[a-zA-Z]+\s?)*[a-zA-Z]$/.test("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8")。请改用/^[a-zA-Z]+(?: [a-zA-Z]+)*$/
  • @nhahtdh 很好。它确实提醒我再次考虑我的答案。删除了不必要的陷阱?
【解决方案3】:
var re = /(([a-zA-Z]+\s*)*[a-zA-Z]+)+/i; 
var str = 'sample test';
var m;

if ((m = re.exec(str)) !== null) {
    if (m.index === re.lastIndex) {
        re.lastIndex++;
    }
    // View your result using the m-variable.
    // eg m[0] etc.
}

供理解或修改check out playground here

【讨论】:

  • re.test('ab ') // true,失败
  • 正则表达式很复杂,解决方案比它应该的复杂。
  • 我也是正则表达式的新手,它看起来对我来说是可以理解的。解决方案有什么问题吗?
  • @SunilBN:正则表达式的格式很差。它不会导致灾难性的回溯,但最后添加少量$ 会导致问题 - 所以不要显示这样的代码。请参阅我的答案以获得更简单的解决方案。另一件事是 OP 想要验证整个字符串,而不仅仅是匹配字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多