正则表达式匹配缓慢
regex match slow
我试图让nodejs应用程序使用超过2mb的ajax上传文件,
客户端我使用FileReader
api保存base64,然后通过FormData
。
我的问题是下面这样的服务器端代码太慢了,我放了console.log
,试图找到哪一部分,当上传更大的文件时,似乎卡在了regex match
上
有什么建议可以改进吗?
https://regex101.com/r/qS2lB2/1
...
console.log(image.data_base64);
// 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvd ...
var matches = image.data_base64.match(/^data:.+'/(.+);base64,(.*)$/);
console.log('done'); // slow
var fileExtension = matches[1];
var base64 = matches[2];
var buffer = new Buffer(base64, 'base64');
...
yield Promise.resolve( filesystem().writeFile(temporaryFilePath, buffer) );
如果您出于某种原因仍想使用正则表达式,可以通过将非尾随的.+
子模式替换为适当的否定字符类来提高性能,这些类涉及的回溯要少得多。
使用
/^data:[^'/]+'/([^;]+);base64,(.*)$/
请参阅regex演示。
说明:
^
-字符串的开头data:
-文字字符序列data:
[^'/]+
-除/
之外的1+个字符'/
-文字斜杠([^;]+)
-第1组:除;
以外的1个字符;base64,
-一个文字字符序列;base,
(.*)
-第2组:0+除换行符以外的任何字符$
—字符串结束
额外的长度意味着正则表达式必须遍历更多的字符串。
在以data:image/jpeg;base64,/9
:开头的字符串上测试regex(使用regex101.com,PHP模式)
添加的字符|步数
0 | 63
1 | 68
2 | 73
10 | 113
100 | 563
每个附加字符为5个步骤。
如何修复正则表达式
(基于characters added=100
,563步)
你最大的问题是
.+
的- 将第一个替换为.+?减少到248步
- 将第二个替换为
.+?
使其从248步增加到34步
性能问题的原因
灾难性的回溯。.+
会吃掉整个字符串,如果它还需要找到更多的字符,它必须返回,逐个释放字符。.+?
是惰性的,这意味着它将尝试在regex中尽快继续,尽可能少地使用字符。
发送multipart/form-data
请求中编码的文件base64是不必要的。FileReader
有一个.readAsArrayBuffer()
方法,它将为您提供可以直接传递给formData.append()
的原始数据(作为ArrayBuffer)。
相关文章:
- java.net和javascript之间正则表达式的差异
- Grunt匹配正则表达式
- 不同浏览器中的空白字符正则表达式行为
- 正则表达式在字符串中找到base64
- 子字符串/正则表达式以获取字符串中保存的 SRC 值
- 调用正则表达式匹配的函数
- 使用正则表达式评估电子邮件地址时出现性能问题
- Javascript 正则表达式 : ^[^/s/]+[a-z]{1,}[0-9]*[-_]*[^/][
- JavaScript正则表达式文本与RegExp对象
- 正则表达式只允许 x 个整数
- 使用正则表达式将输入格式设置为单字符逗号、单字符逗号等
- 改进用于验证付款金额的正则表达式
- 正则表达式与数字中的第二个点匹配
- 键按正则表达式以查找具有负值的小数
- 一个正则表达式,用于从JS中的HTML标记中删除id、样式和类属性
- 将po-box javascript正则表达式转换为c#regex
- 在mongoose中使用正则表达式在对象数组中进行查询搜索
- 正则表达式匹配缓慢
- 用于匹配有限深度嵌套字符串的正则表达式——缓慢、崩溃的行为
- 为什么这个正则表达式执行缓慢