如何通过字符串反向匹配正则表达式?

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 (什么*东西*)
可以匹配的字符串为:你好 你好啊 什么样子的东西好 什么模样的东西最好

但是上述我没有啥思路,希望大家路过有时间看看

感谢大家

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 23

字符串是随机的吗?

2年前 评论
xiaopi (楼主) 2年前
ㅤㅤ (作者) 2年前
xiaopi (楼主) 2年前
laravel_peng
还是使用你第一种方法:
  1. 如果从客户端传过来的字符串 着手会不会好点。
  2. 循环字符串,分析字符串的:长度、英文、符号、以及对应位置。
  3. 解析出部分字符串的的正则表达匹配项
  4. 然后根据这部分 正则表达匹配项 去查询正则数据库获取可能数据。
  5. 循环数据,获取所有最优正则表达式。

从字符串分析,减少获取正则数据库的匹配数据,同样减少循环匹配次数,提高效率。

2年前 评论
xiaopi (楼主) 2年前

如果正则表达式互相不冲突的话,可以用ragel试一下,他会生成一个状态机。

2年前 评论
xiaopi (楼主) 2年前

找一个根据字符串生成正则表达式的包,类似 grex ,把生成的表达式拿去查数据库,存在的就查询,不存在的就新增

2年前 评论
xiaopi (楼主) 2年前
22 (作者) 2年前
xiaopi (楼主) 2年前
22 (作者) 2年前
xiaopi

@22 很抱歉,我没有表达清楚。 那我具体说一下业务: 是一个智能回复功能,即商家用户根据自己的业务话术,给自己的业务话术绑定不同的匹配表达式,用来自动回复不同的业务话术给终端用户。 流程为:

. 终端用户发起请求,询问`你的产品是有哪些`
二.程序接收到终端用户的提问,查找商家设置的正则表达式,找到后,返回该正则表达式绑定的业务话术。如商家设置的表达式为"(.+)产品(.+),匹配成功后,返回业务话术:`我的产品是某某某`
三.重复一、二

整个流程如上,目前实现的是关键字匹配,即商家在业务话术上绑定的是关键字,如"产品"、“哪里”,在收到终端用户的询问后,根据ES,搜索匹配到的关键字,返回对应的话术。 但是不太灵活,所以准备实现正则匹配。

2年前 评论
22 2年前
xiaopi (作者) (楼主) 2年前

我能想到的优化思路:

  1. 使用正则匹配,但是用户上传正则时代码先预跑几次,看下效率如何,效率慢就提醒用户,但决定上传与否还是由用户定
  2. 匹配的结果都存缓存,设置过期时间,这样高频词的匹配效率会很快,低频词虽然慢但出现频率低也可以忍受
  3. 上传正则时配置优先级,匹配到优先级更高的就结束,以减少匹配耗时,且优先级高的正则应提醒用户重点优化以保证效率
2年前 评论
xiaopi (楼主) 2年前

这个不是正则表达式吧。这个应该需要的是中文分词

2年前 评论
xiaopi (楼主) 2年前
wenber
2年前 评论
xiaopi (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!