一个正则表达式的问题

2023-05-16 20:12:25 +08:00
 k2wang
pattern1 = re.compile(r'\b(?:[^\.,]{2,}\s){2,}[^\.,]{2,}(\b,|$)')
pattern2 = re.compile(r'\b(?:[\w]{2,}\s){2,}[\w]{2,}(\b,|$)')
pattern1 与 2 的区别是[^\.,] vs [\w]

数据量是 1000 条数据
pattern1 几十秒还不出结果;
pattern2 运行即拿到结果;

为何两者性能差这么多,有人指点一下吗?
1775 次点击
所在节点    Python
17 条回复
k2wang
2023-05-16 20:29:17 +08:00
纠正:大概 4 万多条数据
CEBBCAT
2023-05-16 20:37:42 +08:00
有没有尝试问一下 ChatGPT ?
feedcode
2023-05-16 20:41:01 +08:00
先问是不是?
2 个不等价哦, "a bc" 这个 r'[\w]{2,}'就匹配不了
k2wang
2023-05-16 20:49:12 +08:00
@CEBBCAT 问了,它说匹配的字符集不同,但不知怎么优化,如果不使用[^]的话,就需要穷举一些常见的英文字符-:"(啥的,解析的准确率要差一点
NCityXu
2023-05-16 20:49:42 +08:00
根据您提供的信息,可以看出 pattern1 和 pattern2 在正则表达式模式中的区别是[^\.,]与[\w]的使用。

pattern1 中的[^\.,]表示匹配一个非逗号和句点的字符,而 pattern2 中的[\w]表示匹配一个单词字符(字母、数字或下划线)。这两个字符集的定义是不同的,可能会导致性能差异。

性能差异可能有以下几个原因:

字符集的复杂性:[^\.,]是一个更为复杂的字符集,它需要检查一个字符是否同时不是逗号和句点。这可能需要更多的计算资源和时间来确定是否匹配。
匹配的字符数量:[^\.,]{2,}要求匹配至少两个连续的非逗号和句点字符,而[\w]{2,}要求匹配至少两个连续的单词字符。如果输入的数据中存在很长的连续字符序列,pattern1 可能需要更多的时间来找到匹配。
数据的特征:具体的数据集特征也可能会影响正则表达式的匹配性能。如果数据中存在更多符合 pattern2 的模式,那么 pattern2 很可能会更快地找到匹配项。
由于缺乏具体的数据示例,以上仅是一些可能导致性能差异的常见原因。实际上,性能差异的具体原因可能需要更详细的分析和测试来确定。如果您能提供更多相关信息或示例数据,我可以尝试给出更具体的解释。
NCityXu
2023-05-16 20:50:03 +08:00
继续问就是了
@k2wang
roycestevie6761
2023-05-16 20:53:20 +08:00
@k2wang 以前遇到正则优化的时候,开发那边叫我用一下 hyperscan ,多模匹配这种,普通的正则根本不行。他们以前搞防火墙规则就用这个框架来做匹配,远远不止 4 万条数据。
k2wang
2023-05-16 20:54:23 +08:00
@feedcode 两者确实不一样哈,[^\.,]会匹配更多的字符,这正是我需要的,如果只是[\w],比较简单,无法满足需要。
附 1 条示例数据:Qiu J., Chen Y., Tian Z., Guizani N., Du X., The security of internet of vehicles network: Adversarial examples for trajectory mode detection, IEEE Netw., 35, pp. 279-283, (2021);
目的:识别出参考文献数据中的标题,The security of internet of vehicles network: Adversarial examples for trajectory mode detection

为什么不匹配作者?
因为作者的匹配规则更麻烦
k2wang
2023-05-16 21:16:09 +08:00
@NCityXu 谢谢,我再追问一下
feedcode
2023-05-16 21:16:38 +08:00
不考虑字符集\w 等于[a-zA-Z0-9_],没有必要写成[\w]
[^\.,] 这个会匹配空格,然后你后面还有空格的匹配,regex 会做 backtrack ,影响性能
k2wang
2023-05-16 21:16:46 +08:00
@roycestevie6761 谢谢,我去了解下 hyperscan
k2wang
2023-05-16 21:23:54 +08:00
@feedcode 感谢,换成[^\.,\s] 之后,问题解决了,这个问题困扰我一天了
gnawll
2023-05-16 23:53:00 +08:00
(问 ChatGPT
aloxaf
2023-05-17 02:39:25 +08:00
正则的灾难性回溯,经历过几年前 CF 全球大中断的程序员应该对其印象深刻
别说几万行,运气不好一行数据就能把基于 NFA 的正则引擎搞挂
https://regex101.com/r/BJbBXy/1
gablic
2023-05-17 09:03:41 +08:00
两个模式之间的区别在于 pattern1 使用字符类[^\.,],它匹配任何不是句号或逗号的字符,而 pattern2 使用字符类[\w],它匹配任何单词字符(字母、数字或下划线)。

pattern1 比 pattern2 慢的原因是[^\.,]匹配的字符比[\w]多。这意味着 pattern1 需要比 pattern2 更多的工作来找到匹配项。

通常,在编写正则表达式时,使用最具体的字符类是一个好主意。这可以帮助提高性能并减少意外匹配的风险。

希望这可以帮助您!如果您有其他问题,请告诉我。
popvlovs
2023-05-17 14:31:22 +08:00
@aloxaf 没错,所以现在我基本都是用 hyperscan 了,因为不是基于回溯实现的,所以没有那么多的 corner case
popvlovs
2023-05-17 14:40:22 +08:00
另外 hyperscan 限定了 x86 arch ,如果是 arm 可以参考这个 https://github.com/VectorCamp/vectorscan

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/940514

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX