考虑正则表达式
^(?:\s*(?:[\%\#].*)?\n)*\s*function\s
旨在匹配以函数定义开头的Octave / MATLAB脚本文件。
但是,这个正则表达式的性能非常慢,而且我不完全确定原因。例如,如果我尝试用Python评估它,
>>> import re, time
>>> r = re.compile(r"^(?:\s*(?:[\%\#].*)?\n)*\s*function\s")
>>> t0=time.time(); r.match("\n"*15); print(time.time()-t0)
0.0178489685059
>>> t0=time.time(); r.match("\n"*20); print(time.time()-t0)
0.532235860825
>>> t0=time.time(); r.match("\n"*25); print(time.time()-t0)
17.1298530102
在英语中,最后一行是说我的正则表达式需要17秒来评估一个包含25个换行符的简单字符串!
我的正则表达式是什么让它变得如此缓慢,我该怎么做才能解决它?
编辑:为了澄清,我希望我的正则表达式匹配以下包含注释的字符串:
# Hello world
function abc
包括任何数量的空格,但不包括
x = 10
function abc
因为那时字符串不以“function”开头。请注意,注释可以以“%”或“#”开头。
答案 0 :(得分:2)
将\s
替换为[\t\f ]
,以便他们不会抓住换行符。这应该只由整个非捕获组(?:[\t\f ]*(?:[\%\#].*)?\n)
完成
问题是你有三个贪婪的消费者都匹配'\n'
(\s*
,(...\n)*
和\s*
}。
在上一个时间示例中,他们会尝试组成a
或任何子字符串{{1}的所有字符串b
,c
和25*'\n'
(每个消费者一个)它首先是,d
是被忽略的,然后是e
现在找到d+e == 25*'\n'
,a
,b
和c
的所有组合,以便e
同时考虑一个或多个变量的空字符串。我现在做数学的时间已经太晚了,但我打赌这个数字很大:D
顺便说一下,regex101是一个很棒的网站,可以试用正则表达式。它们会自动分解表达式并解释它们的部分,甚至还提供调试器。
答案 1 :(得分:0)
要加速,你可以使用这个正则表达式:
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
for (int i=0;i<2;i++){
String string = scanner.next();
int num = scanner.nextInt();
System.out.printf("%-14s %03d %n", string, num); //note the use of printf
// %-14s fifteen characters left-justified o to 14
// %03d padded with leading zero
}
}
由于您实际上并未实际捕获以p = re.compile(r"^\s*function\s", re.MULTILINE)
或#
开头的行,因此您可以使用%
模式并从MULTILINE
关键字所在的同一行开始匹配找到。