如何通过字符串反向匹配正则表达式?
1. 问题描述?
目前有个需求:数据库里内置大量正则表达式,然后业务上接收前端发送的字符串,通过字符串查询数据库,将符合的正则表达式都查询出来。请问有啥好的思路吗?
等于说是反向查询,通过字符串,去寻找可以匹配该字符串的正则表达式。
具体需求如下:
是一个智能回复功能,即商家用户根据自己的业务话术,给自己的业务话术绑定不同的匹配表达式,用来自动回复不同的业务话术给终端用户。
流程为:
一. 终端用户发起请求,询问`你的产品是有哪些`
二.程序接收到终端用户的提问,查找商家设置的正则表达式,找到后,返回该正则表达式绑定的业务话术。如商家设置的表达式为"(.+)产品(.+),匹配成功后,返回业务话术:`我的产品是某某某`
三.重复一、二
整个流程如上,目前实现的是关键字匹配,即商家在业务话术上绑定的是关键字,如”产品”、“哪里”,在收到终端用户的询问后,根据ES,搜索匹配到的关键字,返回对应的话术。
但是不太灵活,所以准备实现正则匹配。
如何实现正则表达式匹配?目前方案都不太理想,
方案一:根据其他条件查询出所有正则表达式,然后通过php遍历,使用preg_match来过滤符合的数据。
优点:实现简单
缺点:效率低,每次都需要查询出所有的数据,并且依次比对,如果碰到复杂的正则,可能很耗时
方案二:通过elasticsearch,将这些正则表达式添加到索引中,然后通过painless script的方式查找,类似
GET index_name/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"is_regular": 1
}
}
]
}
},
"script_fields": {
"aaa": {
"script": {
"lang":"painless",
"source":"""
String a = params.v;
String b = doc['name.raw'];
Pattern pattern = Pattern.compile(b);
if (a =~ pattern) {
return 22;
} else {
return b
}
"""
,"params":{
"v":"字符串"
}
}
}
}
}
结果;报错,查询资料得知,es考虑效率问题,painless脚本不支持动态的正则表达式
请问有其他的解决方案吗?
—————-2022-03-24补充——————
1.正则表达式是用户预先配置的,具有随机性、未知性,所以不好把正则分类
2.字符串是用户随机发送的
或者换一种思路,是否可以让用户配置非正则表达式,即一种类似通配符的方式。
举个例子:
如通配符为:(你好 and 你好啊) or (什么*东西*)
可以匹配的字符串为:你好
你好啊
什么样子的东西好
什么模样的东西最好
但是上述我没有啥思路,希望大家路过有时间看看
感谢大家
字符串是随机的吗?
还是使用你第一种方法:
字符串
着手会不会好点。正则表达匹配项
。正则表达匹配项
去查询正则数据库获取可能数据。从字符串分析,减少获取正则数据库的匹配数据,同样减少循环匹配次数,提高效率。
如果正则表达式互相不冲突的话,可以用ragel试一下,他会生成一个状态机。
找一个根据字符串生成正则表达式的包,类似 grex ,把生成的表达式拿去查数据库,存在的就查询,不存在的就新增
@22 很抱歉,我没有表达清楚。 那我具体说一下业务: 是一个智能回复功能,即商家用户根据自己的业务话术,给自己的业务话术绑定不同的匹配表达式,用来自动回复不同的业务话术给终端用户。 流程为:
整个流程如上,目前实现的是关键字匹配,即商家在业务话术上绑定的是关键字,如"产品"、“哪里”,在收到终端用户的询问后,根据ES,搜索匹配到的关键字,返回对应的话术。 但是不太灵活,所以准备实现正则匹配。
我能想到的优化思路:
这个不是正则表达式吧。这个应该需要的是中文分词。
翻译:PHP Splat: 支持类 Glob 文件匹配和模式匹配的正则工具 看下这个包是否可以满足