我在前一段时间写过的词法分析器中发现了一个错误,它似乎出现在我的正则表达式中。我经常使用regex101,而且我经常忘记在左边从PHP更改为Javascript。无论哪种方式,这是我的正则表达式:
/([\w\.]*)([()]*)/g
现在,除了匹配很多东西外,我应该匹配字符串:
(!one || !two) && three
...上:
(
,one
,two
,)
,three
在PHP中,这个正则表达式就像我想要的那样工作!
在Javascript中,它没有!!!!为什么Javascript会给我这个?!?!
(
,one
,two)
,three
我们的部分two
和)
在同一场比赛中结束......
所以,我的问题是,我怎么能匹配字符串:
(!one || !two) && three
...为:
(
,one
,two
,)
,three
..在Javascript中使用正则表达式上的string.match()
?
谢谢!
答案 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;
答案 1 :(得分:2)
所以,我的问题是,我怎么能匹配字符串:
(!one || !two) && three
...为:
(
,one
,two
,)
,three
..在Javascript中使用正则表达式?
如下:
"(!one || !two) && three".match(/[\w\.]+|[()]/g);
["(", "one", "two", ")", "three"]
为什么Javascript会给我这个?!?!
原始正则表达式/([\w\.]*)([()]*)/g
匹配0个或多个单词字符或点后跟0或更多括号(*
表示0或更多)。你实际上不只是获得two)
之类的东西,还有许多空字符串。要获得您要求的内容,您需要使用交替,如上例所示:您需要单词字符或括号。
我猜你可能一次只想要一个单词char和一个括号,所以我在单词char选项上修改了量词+
而在括号选项上没有任何内容。
答案 2 :(得分:1)
这是一个简单的:
\w+|\(|\)
这是由'或'操作数'|'
分隔的三个不同值它正在寻找的三个值是:
然后,这将匹配每个单词以及开括号和右括号作为单独的匹配。
或者您可以使用括号括号,因为它们都是单个字符,因此无需额外的转义。
\w+|[()]
使用您认为最清楚的那个,因为它有助于将来的维护。