Dart中含OR表达式的正则匹配失效问题求助
问题分析
你遇到的问题是:正则表达式的两个分支分别对应不同的捕获组,当第一个分支(purchaseCode123>(.*?)<)匹配失败时,第二个分支(plan2020Number>(.*?)<)匹配成功,但你通过group(1)获取值时得到null,因为第二个分支的捕获内容存储在group(2)中。
原因说明
正则表达式purchaseCode123>(.*?)<|plan2020Number>(.*?)<定义了两个独立的捕获组:
- 第一个分支的
(.*?)对应捕获组1 - 第二个分支的
(.*?)对应捕获组2
当第一个分支匹配失败、第二个分支匹配成功时,group(1)会返回null,只有group(2)会存储匹配到的plan2020Number标签值。你直接打印group(1)自然拿不到结果。
解决方案
以下几种方式可以解决这个问题,满足你“优先提取purchaseCode,不存在则提取plan2020Number”的需求:
方案1:检查多个捕获组,取第一个非空值
直接在匹配后依次检查group(1)和group(2),优先取group(1),为空则取group(2):
void main() { String str = """<notificationNumber>0373100023320000078</notificationNumber> <lotNumber>1</lotNumber> <placing>12011</placing> <purchaseCode>201770801462077300100101610014520244</purchaseCode> <contractProjectNumber>03731000233200000780001</contractProjectNumber> <tenderPlan2020Info> <ns3:plan2020Number>202003731000233001</ns3:plan2020Number>"""; final regex = RegExp(r'purchaseCode>(.*?)<|plan2020Number>(.*?)<'); final match = regex.firstMatch(str); String? result = match?.group(1) ?? match?.group(2); print(result); // 存在purchaseCode时输出其值,不存在则输出plan2020Number的值 }
方案2:使用命名捕获组
给两个分支的捕获组设置相同的名称,这样无论哪个分支匹配成功,都能通过同一个名称获取值:
void main() { String str = """<notificationNumber>0373100023320000078</notificationNumber> <lotNumber>1</lotNumber> <placing>12011</placing> <purchaseCode>201770801462077300100101610014520244</purchaseCode> <contractProjectNumber>03731000233200000780001</contractProjectNumber> <tenderPlan2020Info> <ns3:plan2020Number>202003731000233001</ns3:plan2020Number>"""; final regex = RegExp(r'purchaseCode>(?<target>.*?)<|plan2020Number>(?<target>.*?)<'); final match = regex.firstMatch(str); print(match?.namedGroup('target')); // 直接通过名称获取目标值 }
方案3:合并分支,共用一个捕获组
将两个标签放在非捕获组中,共用同一个捕获组,利用正则的顺序匹配特性优先匹配purchaseCode:
void main() { String str = """<notificationNumber>0373100023320000078</notificationNumber> <lotNumber>1</lotNumber> <placing>12011</placing> <purchaseCode>201770801462077300100101610014520244</purchaseCode> <contractProjectNumber>03731000233200000780001</contractProjectNumber> <tenderPlan2020Info> <ns3:plan2020Number>202003731000233001</ns3:plan2020Number>"""; final regex = RegExp(r'(?:purchaseCode|plan2020Number)>(.*?)<'); final match = regex.firstMatch(str); print(match?.group(1)); // 优先匹配purchaseCode,不存在则匹配plan2020Number }
注:此方案中,正则会按顺序匹配字符串中第一个出现的
purchaseCode或plan2020Number标签,符合“优先提取purchaseCode”的需求。
内容的提问来源于stack exchange,提问作者Dmitry Bubnenkov
相关产品推荐
相关产品推荐

