【发布时间】:2024-04-26 22:20:02
【问题描述】:
我正在尝试使用 java regex 恢复两个位置
第一个由正则表达式给出:
val r="""(?=(?<=[ ]|^)[^ ]{1,21474836}(?=[ ]|$)(?<=[^A-Z]|^)[A-Z]{1,21474836}(?=[^A-Z]|$))"""
第二个由正则表达式给出
val p="""(?<=(?<=[ ]|^)[^ ]{1,21474836}(?=[ ]|$)(?<=[^A-Z]|^)[A-Z]{1,21474836}(?=[^A-Z]|$))"""
请注意,这两个表达式是相同的,除了第一个“=”在第二个表达式中被替换为“not using neste quantifiers。
我的测试命令如下:
r.findAllMatchIn("a <b/>"*100) //.... some long string of size 600...
p.findAllMatchIn("a <b/>"*100) //.... some long string of size 600...
第一个示例在执行过程中几乎是即时的,而第二个示例需要几十秒。如果我在 REPL 中启动相同的示例,两者都非常快。
这是从哪里来的?如何使第二个表达式更快?
更新:为什么这很重要
请注意,一般情况下,我可以有以下类型的表达式:
[^ ]+[^.]+
我想知道这个正则表达式什么时候可以在给定位置的左边找到,或者什么时候可以结束。 如果我有以下位置的数据:
abc145A
0123456
我希望前一个表达式的末尾匹配位置 1,2,3,4,5 和 6。如果我使用非贪婪重复小丑,那么它将匹配 1,3 和 5。如果我使用贪婪运算符,它只匹配 6。这就是我需要后向断言的原因。或者你会找到我一种方法来定义运算符来找到我正在寻找的位置。
【问题讨论】:
-
我猜双重后视会导致它反复循环相同的字符 - 花费 O(n^2) 时间而不是 O(n) 时间。
-
另一种可能性:{1,21474836} 是一个非常非常大的范围,包含它的后视所花费的时间可能与该范围的大小成正比。
-
我试图将这个数字降低到 2000,但它并没有改变任何东西。
-
如果减少到 10 会怎样? (Java 可能会自动将其缩短为您正在搜索的字符串的长度。)
-
将其减少到 10 可将速度提高 4 倍。
标签: java regex performance scala