这是一个正则表达式,用于从SQL语句中提取表名:
[`'"]
它匹配一个令牌,可以选择将其括在private organizationArray: Array<string>;
const claims = jwtDecode<any>(token);
this.claims = {
email: claims['http://schemas.xmlsoap.org/ws/***/**/***/claims/emailaddress'],
id: claims['http://schemas.xmlsoap.org/ws/***/**/*****/claims/sid'],
name: claims['http://schemas.xmlsoap.org/ws/***/**/****/claims/name'],
expires: new Date(claims['exp'] * 1000),
};
this.organizationArray = claims['http://schemas.*****.**/**/****/**/*******/claims/organization'];
console.log( this.organizationArray.length)
中,并在其前加上由空格包围的FROM等。除了没有前导空格的UPDATE以外。
我们执行许多正则表达式,这是最慢的正则表达式,我不确定为什么。 SQL字符串的最大大小为4k,而在2.2GHz i7 MBP上,执行时间最差的是0.35ms。
这是一个缓慢的输入示例:https://pastebin.com/DnamKDPf
我们可以做得更好吗?如果有问题,将其拆分为多个正则表达式也是一种选择。
答案 0 :(得分:1)
Regex
优化是一个非常复杂的主题,应借助一些工具来完成。例如,我喜欢Regex101,它可以为我们计算Regex
引擎为使pattern
与payload
匹配而必须执行的步骤数。对于您的pattern
和给定的示例,它将打印:
1 match, 22976 steps (~19ms)
您总是可以做的第一件事就是将相似的部分归为一组。例如,FROM
,INTO
和JOIN
看起来很相似,因此我们可以如下编写正则表达式:
(?:\s(?:FROM|INTO|JOIN)\s|\sNEXTVAL[\s\W]*|^UPDATE\s)[\s`'"]*([\w\.-_]+)
对于上面的示例Regex101,打印:
1 match, 15891 steps (~13ms)
尝试找到一些解释和优化Regex
的在线工具,例如myregextester,并计算引擎需要执行的步骤。
答案 1 :(得分:1)
因为比赛通常都快要结束了,所以一种可能性是基本上从结尾开始并回溯,而不是从起点开始并向前回溯,
--no-cache-dir
https://regex101.com/r/SO7M87/1/(154个步骤)
虽然在存在匹配项时这可能会快很多,但在没有匹配项时只是适度的改进,因为模式必须一直追溯到开始(~9000步骤~23k个步骤)
答案 2 :(得分:1)
有一个rule of thumb:
如果存在边界,请勿让引擎尝试匹配每个单个字符。
尝试以下正则表达式(在给定的输入字符串上执行约2500个步骤):
(?!FROM|INTO|NEXTVAL|UPDATE|JOIN)\S*\s*|\w+\W*(\w[\w\.-]*)
注意:您需要的是第一个捕获组。
根据评论,最终的正则表达式(比以前的整洁慢一点):
(?!(?:FROM|INTO|NEXTVAL|UPDATE|JOIN)\b)\S*\s*|\b(?:NEXTVAL\W*|\w+\s[\s`'"]*)([\[\]\w\.-]+)