如何用Index或其他方法在字符串中匹配完整子串(Progress 4GL)
如何实现标签的整词匹配避免子串误匹配?
我读取了一组客户属性(标签),只想保留其中的子集,目前的实现代码如下:
DEFINE VARIABLE tagsToKeep AS CHARACTER. tagsToKeep = "Business Contact,Celebrate 2015,Celebrate 2017,Celebrate 2019,Certificate - Former Holder,Non-MB Church". /* 获取单个标签cRecord的逻辑 */ IF INDEX(tagsToKeep, cRecord) > 0 THEN DO: CREATE ttTag. ASSIGN ttTag.tag-code = cRecord ttTag.constituent-id = ttAccount.pin-string. ttTag.tag-name = cRecord. END.
当前代码存在问题:当待匹配标签是“Certificate”时,它会被误匹配到tagsToKeep中的“Certificate - Former Holder”子串,导致错误创建对应记录。需要实现整词匹配,仅匹配完整的标签字符串。
推荐几种优化实现方法:
方法一:利用分隔符包裹实现精确匹配
给目标标签列表和待匹配标签前后都加上分隔符(逗号),确保只有完整标签会被匹配:
DEFINE VARIABLE tagsToKeep AS CHARACTER. DEFINE VARIABLE taggedToKeepDelimited AS CHARACTER. tagsToKeep = "Business Contact,Celebrate 2015,Celebrate 2017,Celebrate 2019,Certificate - Former Holder,Non-MB Church". taggedToKeepDelimited = "," + tagsToKeep + ",". /* 给列表前后添加逗号 */ /* 获取cRecord的逻辑不变 */ IF INDEX(taggedToKeepDelimited, "," + cRecord + ",") > 0 THEN DO: CREATE ttTag. ASSIGN ttTag.tag-code = cRecord ttTag.constituent-id = ttAccount.pin-string. ttTag.tag-name = cRecord. END.
原理:通过包裹分隔符,,Certificate,不会出现在,Certificate - Former Holder,中,只有完整的标签字符串会被匹配到,避免子串误判。
方法二:使用Progress原生LOOKUP函数(最优方案)
Progress的LOOKUP函数专门用于在逗号分隔的字符串列表中查找完整元素,直接解决问题,代码更简洁:
DEFINE VARIABLE tagsToKeep AS CHARACTER. tagsToKeep = "Business Contact,Celebrate 2015,Celebrate 2017,Celebrate 2019,Certificate - Former Holder,Non-MB Church". /* 获取cRecord的逻辑不变 */ IF LOOKUP(cRecord, tagsToKeep) > 0 THEN DO: CREATE ttTag. ASSIGN ttTag.tag-code = cRecord ttTag.constituent-id = ttAccount.pin-string. ttTag.tag-name = cRecord. END.
原理:LOOKUP函数会遍历逗号分隔的每个元素,仅当待匹配字符串与某个元素完全一致时返回其索引(找不到则返回0),完美适配整词匹配需求。
方法三:用临时表存储允许的标签(适合大量标签场景)
如果标签数量较多或需要多次匹配,可将允许的标签存入临时表,通过表查找实现精确匹配:
DEFINE VARIABLE tagsToKeep AS CHARACTER. DEFINE TEMP-TABLE ttAllowedTags NO-UNDO FIELD tag AS CHARACTER. tagsToKeep = "Business Contact,Celebrate 2015,Celebrate 2017,Celebrate 2019,Certificate - Former Holder,Non-MB Church". /* 初始化允许标签的临时表 */ DO i = 1 TO NUM-ENTRIES(tagsToKeep): CREATE ttAllowedTags. ttAllowedTags.tag = ENTRY(i, tagsToKeep). END. /* 获取cRecord的逻辑不变 */ /* 查找临时表中是否存在该标签 */ FIND FIRST ttAllowedTags WHERE ttAllowedTags.tag = cRecord NO-LOCK NO-ERROR. IF AVAILABLE ttAllowedTags THEN DO: CREATE ttTag. ASSIGN ttTag.tag-code = cRecord ttTag.constituent-id = ttAccount.pin-string. ttTag.tag-name = cRecord. END.
原理:将标签存入临时表后,通过精确字段匹配查找,效率更高,逻辑更直观,适合高频或大量标签的场景。
内容的提问来源于stack exchange,提问作者Felice
相关产品推荐
相关产品推荐

