Ede*_*der 0 ruby regex parsing jruby token
我有以下正则表达式用于数据验证:
lexer = /(?:
(.{18}|(?:.*)(?=\s\S{2,})|(?:[^\s+]\s){1,})\s*
(.{18}|(?:.*)(?=\s\S{2,})|(?:[^\s+]\s){1,})\s*
(?:\s+([A-Za-z][A-Za-z0-9]{2}(?=\s))|(\s+))\s*
(Z(?:RO[A-DHJ]|EQ[A-C]|HIB|PRO|PRP|RMA)|H(?:IB[2E]|ALB)|F(?:ER[2T]|LUP2|ST4Q))\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\s+\d{10}|\s+)\s*
(\d{6})\s*
(.*)(?=((?:\d{2}\/){2}\d{4}))\s*
((?:\d{2}\/){2}\d{4})\s*
(\S+)
)/x
Run Code Online (Sandbox Code Playgroud)
问题是我必须遍历10000行(平均值)的文件,使用正则表达式执行验证,从而导致解析缓慢的应用程序.
filename = File.new(@file, "r")
filename.each_line.with_index do |line, index|
next if index < INFO_AT + 1
lexer = /(?:
(.{18}|(?:.*)(?=\s\S{2,})|(?:[^\s+]\s){1,})\s*
(.{18}|(?:.*)(?=\s\S{2,})|(?:[^\s+]\s){1,})\s*
(?:\s+([A-Za-z][A-Za-z0-9]{2}(?=\s))|(\s+))\s*
(Z(?:RO[A-DHJ]|EQ[A-C]|HIB|PRO|PRP|RMA)|H(?:IB[2E]|ALB)|F(?:ER[2T]|LUP2|ST4Q))\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\S+)\s*
(\s+\d{10}|\s+)\s*
(\d{6})\s*
(.*)(?=((?:\d{2}\/){2}\d{4}))\s*
((?:\d{2}\/){2}\d{4})\s*
(\S+)
)/x
m = lexer.match(line)
begin
if (m) then ...
Run Code Online (Sandbox Code Playgroud)
编辑 在这里,您可以找到我需要解析的一些行:文件
编辑II @Mike R.
我正在解析每行包含25列的文件,每列可能有自己的验证方式.它可以是空格或完整的字符集.
我不相信它的构造很糟糕,它使用的前瞻,可能在我重复代码的部分(我只是不记得捕获组索引\ 1 ... \n,如果这是你的意思意思是!)我也相信灾难性的回溯正在这里发生.
如果你看到这个文件,也许你会明白为什么我这样做!我们以第一列为例.我必须匹配"部件号",我没有任何关于如何执行此操作的规则,示例:
简单的\ S +或(\ S +\s){1,}都不能解决这个问题,因为我不会保证数据的完整性.
泰!
任何改进,建议?
~EderQuiñones
正则表达式在循环中不会改变,因此将lexer =分配拉出循环.("循环不变代码运动.")
我不确定这会更快还是更慢,但重复的子表达式可能只是一个外部重复组.
所以这很明显,我敢肯定,但编写一个真正的解析器可能是有意义的.Ruby有一个名为Treetop的高级PEG解析器生成器.传统方法是Lex + Yacc(例如flex + bison)或者只是实现扫描程序和递归下降解析器的C程序.旧学校,是的,但很容易写,从另一个CRUD程序有点变化.
我同意其他响应者的观点,表达式是不必要的多余,复杂,应该分解为至少两个单独的和更小的表达式.两个表达式可能很有趣,因为它们都可以相反地锚定.
| 归档时间: |
|
| 查看次数: |
695 次 |
| 最近记录: |