PHP和Javascript之间的正则表达式差异

时间:2016-05-16 20:15:55

标签: javascript regex

我在前一段时间写过的词法分析器中发现了一个错误,它似乎出现在我的正则表达式中。我经常使用regex101,而且我经常忘记在左边从PHP更改为Javascript。无论哪种方式,这是我的正则表达式:

/([\w\.]*)([()]*)/g

现在,除了匹配很多东西外,我应该匹配字符串:

(!one || !two) && three

...上:

(onetwo)three

在PHP中,这个正则表达式就像我想要的那样工作!

在Javascript中,它没有!!!!为什么Javascript会给我这个?!?!

(onetwo)three

我们的部分two)在同一场比赛中结束......

所以,我的问题是,我怎么能匹配字符串:

(!one || !two) && three

...为:

(onetwo)three

..在Javascript中使用正则表达式上的string.match()

谢谢!

3 个答案:

答案 0 :(得分:2)

根本原因是这个正则表达式可以匹配一个空字符串,不同的引擎可以不同地处理这些情况。在JS中,如果找到零长度匹配而不检查下一个字符是否是有效匹配的开始,则最有可能使用regex101方法手动推进索引。

要解决此问题,您需要确保正则表达式与空字符串不匹配。因此,您可以使用交替并使用+的另一个部分和*量词的另一个部分,将它们交换到替代分支中:

([\w\.]+)([()]*)|([\w\.]*)([()]+)

请参阅regex demo。在JS代码中,您需要应用一些逻辑来获取正确的值:



var re = /([\w\.]+)([()]*)|([\w\.]*)([()]+)/g; 
var str = '(!one || !two) && three';
var res = [];
while ((m = re.exec(str)) !== null) {
    if (m[4]) {  res.push(m[4]); } 
    else if (m[3]) {  res.push(m[3]); } 
    else if (m[2]) {  res.push(m[2]); } 
    else {  res.push(m[1]); } 
}
document.body.innerHTML = "<pre>" + JSON.stringify(res, 0, 4) + "</pre>";
&#13;
&#13;
&#13;

答案 1 :(得分:2)

  

所以,我的问题是,我怎么能匹配字符串:

(!one || !two) && three 
     

...为:

     

(onetwo)three

     

..在Javascript中使用正则表达式?

如下:

"(!one || !two) && three".match(/[\w\.]+|[()]/g);

["(", "one", "two", ")", "three"]
  

为什么Javascript会给我这个?!?!

原始正则表达式/([\w\.]*)([()]*)/g匹配0个或多个单词字符或点后跟0或更多括号(*表示0或更多)。你实际上不只是获得two)之类的东西,还有许多空字符串。要获得您要求的内容,您需要使用交替,如上例所示:您需要单词字符或括号。

我猜你可能一次只想要一个单词char和一个括号,所以我在单词char选项上修改了量词+而在括号选项上没有任何内容。

答案 2 :(得分:1)

这是一个简单的:

\w+|\(|\)

这是由'或'操作数'|'

分隔的三个不同值

它正在寻找的三个值是:

  1. 任何字母数字字符,其中至少有一个'\ w +'
  2. 一个左括号,记得用反斜杠'('
  3. 一个右括号,也是转义它')'
  4. 然后,这将匹配每个单词以及开括号和右括号作为单独的匹配。

    或者您可以使用括号括号,因为它们都是单个字符,因此无需额外的转义。

    \w+|[()]
    

    使用您认为最清楚的那个,因为它有助于将来的维护。