我有一个文本文件(大小为7GB以上),其中包含重复的行,如下所示:10.00和2.00可能每行不同:
startline money earned 10.00 "300 plus nums n words here" money start 2.00 more words
我想获取值10.00和2.00
我的正则表达式如下:
money earned ([0-9\.]+).*money start ([0-9\.]+)
但这是非常低效的。我花了将近30分钟来扫描1%的文本文件!似乎.*
导致了这种低效率。因此,我选择使用2个单独的正则表达式行来获取这些值,如下所示,这样做效果也更好。
money earned ([0-9\.]+) //this is line 1 capturing 10.00
money start ([0-9\.]+) //this is line 2 capturing 2.00
但这导致赚取的钱(10.00)首先被捕获,因为它是每一行的第一部分而货币开始(2.00)最终成为第二。
我希望扭转这种局面,并且能够首先捕获每条线的货币开始(2.00),然后获得赚取的钱(10.00)。有没有什么方法可以反转正则表达式从行的后面开始并移动到前面。或者,无论如何,当使用单行正则表达式进行扫描时,我可以克服效率低下的问题?
答案 0 :(得分:0)
您是否能够在Java程序接管之前预处理文件?
我使用您的示例作为模板创建了一个7.1 GB的文件。然后我使用grep对其进行预处理,以创建一个中间文件,然后可以更容易地由java处理。
time grep -Eo 'money (earned|start) \d+\.\d+' large_file.txt > results.txt
real 3m12.306s
user 3m7.701s
sys 0m3.222s
results.txt
文件只花了大约三分钟创建,只有168M,格式为:
money earned 10.00
money start 2.00
money earned 10.00
money start 2.00
money earned 10.00
money start 2.00
答案 1 :(得分:0)
money earned ([0-9\.]+).*money start ([0-9\.]+)
^^
有你的问题。这是贪心匹配。这意味着它会在回溯之前开始匹配,并尝试更短的匹配以允许其余的正则表达式匹配。因此,如果你有很多的数据,或者很长的行(甚至很长的字符串,取决于.
是否可以匹配换行符),这可能需要一段时间。它还取决于您的数据的样子。如果在最后money start
之后有大量文字出现,则需要更长时间。如果行中有多个money start
,则跳过除最后一个之外的所有内容。
您可以尝试使用.*?
,这是 lazy 匹配,也就是说,它以 little 开头并扩展它。在许多情况下,这要快得多。