跳到主要内容
版本:1.10.0

正则实体的应用实践

使用正则可以灵活、可靠地实现匹配到已知范围的多种说法,并实现关注字段的抽取。

场景1-抽取用户表述中的条件

用户故事

用户与一个图书管理机器人对话,希望查找符合要求的图书。

用户输入:“找一本关于xxx的书”.

期望机器人可以抽出中间的xxx条件,并作为搜索的关键词。

搭建步骤

  1. 新建一个正则实体“查询图书”,正则表达式:找一本关于(\w+)的书1
  2. 创建词槽“图书查询条件”,选择角色填槽,角色名:1,可填槽实体:查询图书 2
  3. 新建意图“查询图书”,添加一个相似问:[找一本关于历史的书]{"entity": "查询图书"} 3
  4. 新建一个对话流程技能
    1. 触发意图选择“查询图书”
    2. 进入画布,开始单元后接询问填槽单元,选择待填词槽为“图书查询条件”
    3. 后接消息发送单元,回复内容为:“查找图书的条件:{slot=图书查询条件}” 45
  5. 技能状态改为已生效,点击训练机器人
  6. 用测试机器人中测试对话效果,可以看到机器人抽取出了图书的条件,并将其填入“图书查询条件”词槽中。 6

正则式的常用规则

在搭建示例中,我们将正则实体的表达式配置为:找一本关于(\w+)的书,其中:

  • \w 表示任意汉字、英文字母、数字
  • + 表示重复至少1次(1-N)

因此:

  • \w+ 表示长度至少为1的连续汉字、英文字母或数字

提炼和扩展一些正则式的常用规则:

  • \d* 表示连续0-N个数字
  • ? 表示重复0或者1次
  • * 表示重复任意次(0-N)
  • (ab)+:表示至少重复1次ab,例如:ab,abab,ababab

正则实体的角色填槽

  • 在搭建示例中,括号中的内容(\w+)会被单独作为实体抽出,并带有角色名。

    • 角色名按照括号从左到右的顺序默认为1、2、3…

    • 角色名支持通过使用(?P<name>xxxx)的写法自定义,例如:找一本关于(?P<book>\w+)的书。对应的,词槽中的角色名需要修改为book。

  • 如果不希望机器人将某些括号中的内容抽出,需要把括号原内容(xxx)改写成(?:xxx),这样括号里面的内容,就不会被单独抽出实体以及角色。

尝试支持更多的说法

  1. 用户的表述不会只有找一本关于xxx的书这一种,用户还可能会说:

    • 我想找一本关于xxx的书
    • 找关于xxx的书
    • 搜xxx的书
    • 找一本xxxx的书
  2. 用户可能不说“一本”或者“关于”,因此这两部分重复0或1次,同时无需被抽取出来。将正则表达式优化为:找(?:一本)?(?:关于)?(?P<book>\w+)的书。可以识别到的说法扩展为:

    • 找一本关于chatbot的书
    • 找chatbot的书
    • 找一本chatbot的书
    • 找关于chatbot的书
  3. 用户对“查找”的表述有很多,如“搜索”、“找”等,因此可以用“|”将这些表述拼接起来,表达或关系。将正则表达式优化为:(?:搜|查找|找)(?:一本)?(?:关于)?(?P<book>\w+))的书。可以识别到的说法扩展为:

    • 搜一本关于chatbot的书
    • 查找一本关于chatbot的书
    • 找一本关于chatbot的书
    • 搜一本chatbot的书
    • 查找一本chatbot的书
    • 搜chatbot的书

场景2-填入多个词槽

用户故事

某ASR项目中,用户说IP地址时,ASR结果样式为:10.12点2.245。

期望机器人可以将其转换成正确的书写格式10.12.2.245

搭建步骤

  1. 新建一个正则实体“IP地址”,正则表达式:(\d+)\.(\d+)点(\d+)\.(\d+)

  2. 创建4个词槽“ip1”至“ip4”,将角色名@填槽实体一次配置为为1@IP地址2@IP地址3@IP地址4@IP地址

  3. 新建对话流程技能

    1. 新建触发意图“抽取ip”
    2. 进入画布,开始单元后配置四个询问填槽单元,待填词槽依次为“ip1”至“ip4”
    3. 后接消息发送单元,回复内容为:“{slot=ip1}.{slot=ip2}.{slot=ip3}.{slot=ip4}”
  4. 技能状态改为已生效,点击训练机器人

  5. 用测试机器人中测试对话效果,可以看到机器人抽取出了ip地址,并将其转换为正确的格式打印出来。

更完善的正则表达式

正则匹配很容易出错,需要考虑各种可能的情况

以IP地址为例,考虑以下的bad cases:

  • 1111.1.2.3
  • 333.1.2.3
  • 256.1.2.3
  • 1.2.3.2555
  • 1.2.3333.4
  1. ip地址的数字范围,每一段为0-255之前,因此应该为1-3位数字,可以用{1,3}限制数字的范围: (\d{1,3})\.(\d{1,3})点(\d{1,3})\.(\d{1,3})

  2. 每个字段范围是0-255,需要考虑数字的取值范围,例如当数字为3位时,最高位只能是1或者2 ([012]?[0-9]{1,2})\.([012]?[0-9]{1,2})点([012]?[0-9]{1,2})\.([012]?[0-9]{1,2})