对象的快速正则表达式
项目描述
pyrefo:对象的快速正则表达式
该项目基于refo和论文正则表达式匹配:虚拟机方法,它使用 cffi 用 c 扩展 python 以加快处理性能。
本项目做了以下工作:
- 完全兼容 refo api,支持所有模式和 match、search、finditer 方法;
- 修复论文中包含的 c 源代码错误;
- 使用cffi用c扩展python;
- 添加支持部分匹配的新功能;
- 添加
Phrase
可以实现'ab'
匹配['a', 'b', 'c']
列表的新模式;
如何使用它
"ab"
是Literal("a")+Literal("b")
"a*"
是Star(Literal("a"))
"aab?"
是Literal("a")+Literal("a")+Question(Literal("b"), greedy=False)
a{3,4}
是Repetition(Literal("a"), 3, 4, greedy=False)
"(ab)+|(bb*)?"
是
a = Literal("a")
b = Literal("b")
regex = Plus(a + b) | Star(b + b, greedy=False)
您还可以将组分配给任何子匹配,然后检索匹配的内容,例如:
regex = Group(Plus(a + b), "foobar") | Star(b + b, greedy=False)
m = match(regex, "abab")
print(m.span("foobar"))
pyrefo
提供match
, search
, findall
,finditer
搜索功能:
- match:从第一个位置匹配模式
- 搜索:从第一个位置搜索模式直到找到一个
- findall:查找所有匹配的结果
- finditer:返回所有匹配结果的迭代器
pyrefo
提供以下谓词:
- 任何
- 文字
- 星星
- 加
- 问题
- 团体
- 重复
- 短语
性能测试
先决条件
import jieba
text = '为什么在本店买东西?因为物流迅速+品质保证。为什么我购买的每件商品评价都一样呢?因为我买的东西太多了,积累了很多未评价的订单,所以我统一用这段话作为评价内容。如果我用了这段话作为评价,那就说明这款产品非常赞,非常好!'
tokens = list(jieba.cut(text))
CPython
- pyrefo
from pyrefo import search, Group, Star, Any, Literal
%timeit search(Group(Literal('物流') + Star(Any()) + Literal('迅速'), 'a'), tokens)
95.9 µs ± 472 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
- 参考资料
import refo
%timeit refo.search(refo.Group(refo.Literal('物流') + refo.Star(refo.Any()) + refo.Literal('迅速'), 'a'), tokens)
1.03 ms ± 7.27 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
- 回覆
import re
%timeit re.search('(物流.*速度)', text)
989 ns ± 4.69 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
派皮
- pyrefo
from pyrefo import search, Group, Star, Any, Literal
%timeit search(Group(Literal('物流') + Star(Any()) + Literal('迅速'), 'a'), tokens)
53.4 µs ± 28 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
- 参考资料
import refo
%timeit refo.search(refo.Group(refo.Literal('物流') + refo.Star(refo.Any()) + refo.Literal('迅速'), 'a'), tokens)
78 µs ± 35.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
- 回覆
import re
%timeit re.search('(物流.*速度)', text)
347 ns ± 3.26 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)