为什么" a * a +"和"(a {2,3})* a {2,3}"匹配" aaaa"而#34;(a {2,3})*"不能?

时间:2018-01-03 01:36:40

标签: regex

我对app.post("/user", (req, res) => { console.log(req.body); //req.body can consist of 1 or more of the following // { FirstName, LastName, Email, Interests, UserRole } const CreatedAt = Date.now(); if (req.body.Name) { User.findOne({ Name: req.body.Name }) .then(user => { //mutate user: Object.keys(req.body).reduce( (user,key)=>{ user[key]=req.body[key]; return user; } ,user ); //set UpdatedAt user.UpdatedAt = Date.now(); //http://mongoosejs.com/docs/documents.html // maybe outdated, does not mention promise but // you could try return user.save() return new Promise( (resolve,reject)=> user.save( (err,user)=> (err) ? reject(err) : resolve(user) ) ) }) .then(user=>res.json({message:user})) .catch(err => res.json({message:"User could not be found."})); } else { res.json({message:"Please provide an email and a password."}); }; }); 的理解是它消耗尽可能多的角色(贪婪)但是"回归"必要时。因此,在*中,a*a+会将一个(或者更多?)字符返回a*,以便它可以匹配。

然而,在a+中,为什么不是第一个"实例" (a{2,3})*的{​​{1}}给第二个"实例"所以第二个可以匹配吗?

此外,在a{2,3}中,第一部分似乎确实为第二部分赋予了一个角色。

3 个答案:

答案 0 :(得分:2)

您的问题的一个简单解决方法是将aaaa与正则表达式^(a{2,3})*$匹配。

你的问题是:

  

(a{2,3})*的情况下,正则表达式似乎没有消耗那么多   角色尽可能。

我建议不要回想角色。相反,关键是接受

一旦正则表达式接受您的字符串,匹配将结束。模式a{2,3}仅匹配aaaaa。因此,在将aaaa(a{2,3})*匹配的情况下,贪婪引擎会匹配aaa。然后,它不能与更多a{2,3}匹配,因为只剩下一个a。虽然它能够使正则表达式引擎做回溯并匹配额外的a{2,3},但它不会。正则表达式aaa现在被接受,因此正则表达式引擎不会进行昂贵的回溯。

如果在正则表达式的末尾添加$,它只会告诉正则表达式引擎部分匹配是不可接受的。此外,通过接受和回溯来解释(a{2,3})*a{2,3}案例很容易。

答案 1 :(得分:1)

主要问题是:

  

我对*的理解是它消耗尽可能多的字符(贪婪)但是"回馈"必要时

这是完全错误的。这不是贪婪的意思。

贪婪只是意味着"使用最长的匹配"。它没有回馈任何东西。

一旦用新的理解来解释表达式,一切都有意义。

  1. a*a+ - 零个或多个a后跟一个或多个a

  2. (a{2,3})*a{2,3} - 两个或三个中的零个或多个a后跟两个或三个a(注意:要记住的关键是"零或更多",第一部分不匹配任何字符被视为匹配)

  3. (a{2,3})* - 两个或三个中的零个或多个a(这意味着在匹配三个a后,最后一个a左侧无法匹配)

答案 2 :(得分:0)

只有在匹配失败时才会进行回溯,但aaa是有效匹配,可以使用否定前瞻(?!a)来阻止匹配后跟a

compare

(aaa?)*

(aaa?)*(?!a)