SQL Server 2019正则匹配优化:带ml的数字匹配优先级问题
正则表达式调整方案
问题背景
我目前使用以下正则表达式,用于匹配以最多9位数字开头、后缀为ml的内容,且要求该数字不在1900-2100范围内:
(?i)(?<!\b(?:19|2[01])\d(?=\d))(?<!\b(?:19|2[01])(?=\d{2}))(?<!\b(?:1(?=9\d{2}))|2(?=[01]\d{2}))(?!\b(?:19|2[01])\d\d)\d{0,9}ml$
该正则用于Microsoft SQL 2019的函数中,大部分场景匹配正常,但遇到单引号后接两位数字的情况时,匹配结果不符合预期:
- 案例1:内容为
'19750ml',当前匹配0ml,期望匹配750ml - 案例2:内容为
Test '<strong>2529ml</strong>',期望匹配29ml
需要调整正则逻辑,让单引号后两位数字之后的匹配拥有最高优先级。
以下是当前的匹配示例(含正常与问题场景):
- Mary had a little lamb 1980750ml
- Test 19819ml
- Test 198218ml
- Test 2123456ml
- Test 20349876ml
- Test 209912345ml
- Test 1999123456ml
- Test 987654321ml
- Test '19750ml(问题案例)
- Test 1988ml
- Test 9999ml
- Test 2000ml
- Test 100ml
- Test '2529ml(期望匹配29ml)
调整后的正则表达式
(?i)(?<=')\d{2}(?!(?:19|2[01])\d{2}\b)\d{0,9}ml$|(?<!')(?!\b(?:19|2[01])\d{2}\b)(?<!\b(?:19|2[01])\d(?=\d))(?<!\b(?:19|2[01])(?=\d{2}))(?<!\b(?:1(?=9\d{2})|2(?=[01]\d{2})))\d{0,9}ml$
逻辑说明
正则采用分支结构,优先处理单引号后的场景,确保优先级:
- 第一个分支
(?<=')\d{2}(?!(?:19|2[01])\d{2}\b)\d{0,9}ml$:(?<='):匹配单引号之后的内容\d{2}:跳过单引号后的前两位数字(?!(?:19|2[01])\d{2}\b):确保后续数字不在1900-2100范围内\d{0,9}ml$:匹配最多9位数字+ml,且以ml结尾
- 第二个分支:保留原正则的匹配逻辑,新增
(?<!')确保前面没有单引号,避免与第一个分支冲突,保证非单引号场景的正常匹配。
内容的提问来源于stack exchange,提问作者Craig
相关产品推荐
相关产品推荐

