4 回答
TA贡献1801条经验 获得超8个赞
import "regexp"包 regexp 实现正则表达式搜索。
接受的正则表达式语法与 Perl、Python 和其他语言使用的通用语法相同。更准确地说,它是 RE2 接受并在https://golang.org/s/re2syntax中描述的语法 ,\C 除外。有关语法的概述,请运行
go doc regexp/syntax此包提供的正则表达式实现保证按输入大小线性运行。(这是大多数正则表达式的开源实现不保证的属性。)有关此属性的更多信息,请参阅
http://swtch.com/~rsc/regexp/regexp1.html
或任何有关自动机理论的书。
通过设计,Go 正则表达式保证在输入的大小上按线性时间运行,这是正则表达式的其他一些实现无法保证的属性。请参阅正则表达式匹配可以简单快速。
TA贡献1862条经验 获得超6个赞
使用这个:
^DETAIL:\s*+Key[^\(]++\((.+)\)[^\(]+\(([^\)]+)\) already exists
解释:
首先,原始正则表达式似乎与整个键组不匹配,您停在了lower(internal_name::text
,遗漏了复合键的某些列以及一个不平衡的括号。如果你这样修改它,它应该可以捕获复合键。如果不应该这样做,请告诉我:
^DETAIL:.[^\(]+.(.+)\)[^\(]+.(.[^\)]+). already exists
只需更改它,正则表达式就可以“运行”,但仍然很慢。
他的主要原因之一就是这个[^\(]+
。它首先匹配并DETAIL: Failing row contains(space)
继续匹配正则表达式的其余部分。它不会匹配,所以它回溯到少一个字符,直到DETAIL: Failing row contains
并继续正则表达式的其余部分。它不会匹配,所以会回到DETAIL: Failing row contain
......等等。
避免这种情况的一种方法是使用所有格量词。这意味着一旦你获取了一些东西,你就无法返回。所以使用这个[^\(]++
而不是这个[^\(]+
(即:)^DETAIL:.[^\(]++.(.+)\)[^\(]+.(.[^\)]+). already exists
使正则表达式将步数从 28590 减少到 1290。
但你仍然可以改进它。如果您知道您所需的数据使用关键字key
,请使用它!这样,由于它不存在于失败的示例中,它会使正则表达式很快失败(一旦它读取 DETAIL 和下一个词)
所以如果你使用^DETAIL:\s*+Key[^\(]++.(.+)\)[^\(]+.(.[^\)]+). already exists
步骤现在只有 12。
如果您觉得使用key
过于具体,您可以使用不太通用的东西来尝试找到“不是'失败'”。像这样:
^DETAIL:\s*+(?!Fail)[^\(]++.(.+)\)[^\(]+.(.[^\)]+). already exists
这样就是17步。
最后,您可以调整匹配内容的正则表达式。
改变这个:
^DETAIL:\s*+Key[^\(]++.(.+)\)[^\(]+. # <============= here, use \( instead (.[^\)]+). already exists
这样:
^DETAIL:\s*+Key[^\(]++.(.+)\)[^\(]+\((.[^\)]+). already exists
这将步骤从 538 减少到 215,因为你减少了回溯。
然后,在删除几个无用的点并将一些(应该是括号的)点替换为\(
或\)
(个人品味)之后,您将获得最终的正则表达式:
^DETAIL:\s*+Key[^\(]++\((.+)\)[^\(]+\(([^\)]+)\) already exists
TA贡献1820条经验 获得超2个赞
这是一个正则表达式怪物:)
为什么不拆分 2 个正则表达式?
检查是否
already exists
匹配(非常快)使用现有的正则表达式提取要显示的数据
^DET.[^\(]+.(.[^\)]+).[^\(]+.(.[^\)]+)
那应该可以大大加快您的代码速度。(你甚至可以像我一样缩短细节)
TA贡献1851条经验 获得超4个赞
这并不是问题的真正答案,但我认为问题可能出在贪婪的运营商身上。无论如何,我认为你应该让它的一部分变得懒惰以快速失败。
我使用了这种模式,在 regex101 上的所有语言引擎上都可以:
^DETAIL:.+?\((.+)\).+?\((.+)\) already exists.
- 4 回答
- 0 关注
- 160 浏览
添加回答
举报