Flutter中如何使用正则表达式按子串过滤字符串列表
问题原因
- 原有正则
RegExp(r'[a-zA-Z]+')仅提取字符串中第一个连续字母序列,例如+XYZ (NAM)会优先提取到XYZ,若过滤词只有NAM则匹配失败;同时使用!强制解包匹配结果,若字符串无匹配的字母序列会直接抛出空异常。 - 另一款正则
RegExp(r'^\+.([a-zA-Z]+) \(([a-zA-Z]+).\).$')强制限定了字符串必须为+xxx (xxx)的格式,纯字母串、仅括号包裹的字符串都无法匹配,导致无结果返回。
解决方案
直接构造包含所有过滤词的正则表达式,判断字符串是否存在任意一个过滤词即可,不需要提前提取字母序列:
void main() { List<String> names = ["NAM", "XYZ", "+QWE (HJB)", "+XYZ (NAM)", "(NAM)"]; List<String> filter = ["NAM", "HJB"]; // 构造正则,join拼接多个过滤词,RegExp.escape避免过滤词含特殊正则字符导致匹配异常 final matchReg = RegExp(filter.map(RegExp.escape).join('|')); // 如需忽略大小写匹配,可改为RegExp(filter.map(RegExp.escape).join('|'), caseSensitive: false) for (var element in names) { if (matchReg.hasMatch(element)) { print(element); } } }
运行输出
NAM +QWE (HJB) +XYZ (NAM) (NAM)
如果需要保留先提取字母序列再匹配的逻辑,可以提取所有字母序列后判断是否存在符合条件的项,避免空异常:
void main() { List<String> names= ["TEX","TOL","+TEX (TOL)","+TOL (TEX)", "(NAM)"]; List<String> filter = ["TEX", "TOL"]; final regexp = RegExp(r'[a-zA-Z]+'); for(var e in names){ // 提取所有连续字母序列,过滤空值后判断是否有任意项在过滤列表中 final allLetterSegments = regexp.allMatches(e).map((m) => m.group(0)).whereType<String>(); if(allLetterSegments.any(filter.contains)) { print(e); } } }
内容的提问来源于stack exchange,提问作者max0l
相关产品推荐
相关产品推荐

