Qwen2.5-7B-Instruct实战案例:用自然语言生成正则表达式+测试用例+边界说明
Qwen2.5-7B-Instruct实战案例:用自然语言生成正则表达式+测试用例+边界说明
你是不是也遇到过这种情况?产品经理提了个需求:“帮我写个正则,能匹配所有手机号,但排除掉测试号段186开头的。” 你心里一咯噔,正则表达式这玩意儿,语法像天书,写起来费劲,调试起来更费劲。好不容易写出来,还得绞尽脑汁想各种边界情况去测试。
现在,有了Qwen2.5-7B-Instruct,这个痛点可以轻松解决了。这个7B参数的“大块头”模型,逻辑推理和代码能力远超轻量版,让它来当你的“正则表达式私人助理”,再合适不过。今天,我就带你看看,如何用自然语言,让这个AI助手帮你一站式搞定正则表达式的生成、测试和边界说明。
1. 为什么需要AI来写正则?
在深入实战之前,我们先聊聊为什么这件事值得做。正则表达式是程序员和数据分析师的利器,但它的学习曲线陡峭,语法晦涩难懂。
传统写正则的流程通常是这样的:
- 需求模糊:产品或业务方用自然语言描述匹配规则。
- 手动翻译:开发者将自然语言“翻译”成正则语法,这个过程极易出错。
- 反复调试:写个简单的测试脚本,用几个例子跑一下,发现不对再回去改正则。
- 遗漏边界:往往只测试了正常情况,一些奇怪的边界情况(如空字符串、超长输入、特殊字符)容易被忽略,为线上问题埋下隐患。
整个过程耗时耗力,而且对经验依赖很大。
而用Qwen2.5-7B-Instruct之后,流程变成了这样:
- 自然语言描述:你直接用大白话把需求告诉AI。
- 一键生成:AI瞬间返回正则表达式,并附上清晰的解释。
- 附带测试:AI同时提供覆盖各种情况的测试用例。
- 边界预警:AI会主动指出这个正则可能处理不了的边界情况。
从“人适应机器语法”变成了“机器理解人的意图”,效率和可靠性都大大提升。接下来,我们就启动服务,开始实战。
2. 环境准备与快速启动
首先,你需要一个已经部署好的Qwen2.5-7B-Instruct服务。如果你用的是基于Streamlit的镜像,启动非常简单。
启动服务:
- 找到并运行项目主程序(通常是
app.py或streamlit run app.py)。 - 首次启动需要加载7B模型,耐心等待20-40秒,控制台会显示加载进度。
- 看到宽屏聊天界面在浏览器中打开,就意味着服务启动成功了。
界面初览: 启动后,你会看到一个清爽的宽屏界面。左侧是控制台,有两个关键滑块:
- 温度(创造力):建议保持默认的0.7,这样AI的回答在准确性和创造性上有很好的平衡。
- 最大回复长度:对于生成正则和代码的场景,可以调到1024或更高,确保回复完整。
右侧就是我们的主聊天区域了。一切就绪,让我们开始第一个任务。
3. 实战案例一:生成一个复杂的正则表达式
我们从一个相对复杂的需求开始,看看Qwen2.5-7B-Instruct如何应对。
我的需求是: “写一个Python的正则表达式,用来匹配中国大陆的手机号码。规则是:以1开头,第二位是3、4、5、6、7、8、9中的一个,总共11位数字。但是,需要能识别出号码中的运营商:移动(134-139, 147, 150-152, 157-159, 165, 172, 178, 182-184, 187-188, 198)、联通(130-132, 145, 155-156, 166, 171, 175-176, 185-186)、电信(133, 149, 153, 162, 173-174, 177, 180-181, 189, 190, 191, 193, 199)。最后,这个正则要能方便地提取出号段(前三位)和剩余号码。”
我把这段话直接输入到聊天框,点击发送。很快,AI给出了回复。
AI生成的代码与解释:
import re
# 综合匹配中国大陆手机号并识别运营商的正则表达式
pattern = r'^(1(3[0-9]|4[5-9]|5[0-9]|6[0-9]|7[0-9]|8[0-9]|9[0-9])\d{8})$'
# 为了清晰识别运营商,我们使用命名捕获组来分别匹配不同运营商号段
phone_regex = re.compile(r‘^(?P<all>(?P<prefix>1(3[4-9]|47|5[0-2]|5[7-9]|65|72|78|8[2-4]|8[7-8]|98)|1(3[0-2]|45|5[5-6]|66|71|7[5-6]|8[5-6])|1(33|49|53|62|7[3-4]|77|8[0-1]|89|90|91|93|99))\d{8})$’)
def parse_phone_number(phone_str):
"""
解析手机号码,返回运营商信息和分段号码。
"""
match = phone_regex.match(phone_str)
if not match:
return None
full_number = match.group(‘all’)
prefix = match.group(‘prefix’)
# 根据前缀判断运营商
if prefix.startswith(('134', '135', '136', '137', '138', '139', '147', '150', '151', '152', '157', '158', '159', '165', '172', '178', '182', '183', '184', '187', '188', '198')):
carrier = “中国移动”
elif prefix.startswith(('130', '131', '132', '145', '155', '156', '166', '171', '175', '176', '185', '186')):
carrier = “中国联通”
elif prefix.startswith(('133', '149', '153', '162', '173', '174', '177', '180', '181', '189', '190', '191', '193', '199')):
carrier = “中国电信”
else:
carrier = “未知运营商”
return {
“full_number”: full_number,
“prefix”: prefix,
“remaining”: full_number[3:], # 第4位到第11位
“carrier”: carrier
}
# 测试用例
test_numbers = [
“13800138000”, # 移动
“18612345678”, # 联通
“18987654321”, # 电信
“12345678901”, # 非法第二位
“1380013800”, # 少于11位
“138001380001”, # 多于11位
“” # 空字符串
]
print(“测试结果:”)
for num in test_numbers:
result = parse_phone_number(num)
if result:
print(f“号码 {num} -> 运营商: {result[‘carrier’]}, 号段: {result[‘prefix’]}, 剩余号码: {result[‘remaining’]}”)
else:
print(f“号码 {num} -> 匹配失败”)
AI提供的核心解释:
- 正则核心:
^1(3[0-9]|4[5-9]|5[0-9]|6[0-9]|7[0-9]|8[0-9]|9[0-9])\d{8}$确保了1开头、第二位合法、总长11位的基本规则。 - 运营商识别:它没有用一个巨长无比的正则直接匹配所有号段,而是巧妙地用了命名捕获组(
?P<prefix>...)先提取出前三位,然后在Python代码里用startswith()判断运营商。这样正则更清晰,代码也更易维护。 - 结构化返回:函数直接返回一个字典,包含完整号码、号段、剩余号码和运营商,开箱即用。
同时,AI还附上了测试用例和边界说明:
- 正常用例:包含了移动、联通、电信的典型号码。
- 异常用例:第二位非法的号码、长度不对的号码。
- 边界情况:空字符串。AI特别指出,正则开头的
^和结尾的$确保了必须完整匹配11位,空字符串自然匹配失败,符合预期。
这个回复不仅给了代码,还给了思路和验证方法,直接复制粘贴就能跑起来测试,非常贴心。
4. 实战案例二:从测试用例反推正则规则
有时候,我们手头只有一些正例和反例,需要反推出正则规则。这对AI的逻辑推理能力要求更高。
我这样问AI: “我这里有一些字符串,符合规则的包括:‘user_123’, ‘item-456’, ‘test_789-abc’。不符合规则的包括:‘123user’, ‘user@name’, ‘ab’, ‘averylongstringthatisnotvalid’。请帮我分析规则,并写出一个能匹配所有符合规则字符串的Python正则表达式。”
AI的分析与生成:
AI没有直接写正则,而是先给出了它的推理过程: “让我们先分析符合和不符合的字符串,找出模式: 符合的:user_123 (字母,下划线,数字), item-456 (字母,连字符,数字), test_789-abc (字母,下划线,数字,连字符,字母)。 不符合的:123user (以数字开头), user@name (包含@符号), ab (太短,且只有字母), averylongstringthatisnotvalid (可能过长或包含空格?实际上它全是字母,可能规则要求必须有数字或特定分隔符)。
推测规则可能是:
- 必须以字母开头。
- 只能包含字母、数字、下划线(_)和连字符(-)。
- 必须至少包含一个数字。
- 长度可能有一定范围?从‘ab’被排除看,可能要求长度>=3。从长字符串被排除看,可能长度有上限,或者它被排除是因为不含数字(推测3更可能)。
先基于前三点写正则:^[a-zA-Z][a-zA-Z0-9_-]*\d[a-zA-Z0-9_-]*$。这个规则要求至少一个数字,且字母开头。”
然后,它给出了优化后的正则和测试代码:
import re
# 根据分析编写的正则表达式
# 规则:字母开头,仅包含字母数字下划线连字符,且必须至少包含一个数字。
pattern = r‘^[a-zA-Z][a-zA-Z0-9_-]*\d[a-zA-Z0-9_-]*$’
regex = re.compile(pattern)
test_strings = [
“user_123”, # 符合
“item-456”, # 符合
“test_789-abc”, # 符合
“123user”, # 不符合:数字开头
“user@name”, # 不符合:包含@
“ab”, # 不符合:无数字
“averylongstringthatisnotvalid”, # 不符合:无数字
“Valid_1”, # 新增:符合
“A-2-b”, # 新增:符合
“noNumberHere”, # 新增:不符合
]
print(“测试反推规则的正则:”)
for s in test_strings:
match = regex.match(s)
print(f“{s:30} -> {‘匹配成功’ if match else ‘匹配失败’}”)
AI的总结与边界提醒: “这个正则满足了已给示例。但需要注意:
- 它没有限制长度。如果原规则有长度限制(比如3-20个字符),需要修改为
^[a-zA-Z][a-zA-Z0-9_-]{2,19}\d[a-zA-Z0-9_-]*$并不准确,因为数字位置不定。更稳妥的是匹配后再检查长度。 - 它要求至少一个数字。如果‘ab’是因为长度而非数字被排除,那么规则可能不同。 建议用更多测试用例验证,特别是边界情况,如空串、非常长的串、纯数字串等。”
这个案例展示了AI强大的归纳和推理能力。它不只是模式匹配,而是在分析正反例后,主动提出对潜在规则的假设,并指出当前方案的局限性,提醒我需要更多信息来确认。这就像一个经验丰富的同事在和你一起讨论需求。
5. 实战案例三:生成正则并附带完整测试套件
对于要上生产环境的代码,一个健壮的正则表达式必须配有完整的测试。我们可以让AI一次性完成。
我的指令: “为‘提取字符串中所有符合‘YYYY-MM-DD’格式的日期’这个需求,写一个Python正则表达式。请同时生成一个完整的pytest测试套件,覆盖以下情况:1. 标准日期(如‘2023-10-01’)。2. 月份和日期为个位数时带前导零和不带前导零的情况(如‘2023-9-5’)。3. 非法日期(如‘2023-13-01’, ‘2023-02-30’)。4. 字符串中包含多个日期。5. 字符串中混入其他类似格式但不是日期的内容(如‘2023-10-001’)。最后,请指出这个简单正则的局限性。”
AI的一站式输出:
import re
from datetime import datetime
def extract_dates(text):
"""
使用正则表达式提取YYYY-MM-DD格式的日期。
注意:此正则只做格式校验,不保证日期真实存在。
"""
# 正则表达式:YYYY-MM-DD,月份01-12,日期01-31
date_pattern = re.compile(r‘\b(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])\b’)
matches = date_pattern.findall(text)
# 将匹配的元组转换为字符串列表
return [‘-’.join(match) for match in matches]
# 示例使用
sample_text = “项目开始于2023-09-01,结束于2024-1-15。中间有个错误日期2023-13-45。另一个日期是2023-02-28。”
print(“提取到的日期:”, extract_dates(sample_text))
紧接着,AI生成了详细的pytest测试套件:
# test_date_extractor.py
import pytest
from your_module import extract_dates # 假设上面的函数保存在your_module.py
def test_standard_date():
assert extract_dates(“今天是2023-10-01。”) == [“2023-10-01”]
def test_single_digit_month_day():
# 注意:正则要求两位数字,所以‘2023-9-5’不会被匹配
assert extract_dates(“日期2023-09-05和2023-10-1。”) == [“2023-09-05”] # ‘2023-10-1’不匹配
# 如果需要匹配单数字,正则应改为 r‘\b(\d{4})-(\d{1,2})-(\d{1,2})\b’,但这里按原需求。
def test_invalid_numeric_range():
# 正则只检查数字范围,不检查日期有效性,所以‘2023-13-01’(月份13)不匹配,但‘2023-02-30’(2月30日)会匹配!
assert extract_dates(“无效月2023-13-01。”) == []
assert extract_dates(“无效日2023-02-30。”) == [“2023-02-30”] # 这是此正则的缺陷!
def test_multiple_dates():
assert extract_dates(“从2023-01-01到2023-12-31。”) == [“2023-01-01”, “2023-12-31”]
def test_mixed_content():
assert extract_dates(“编号2023-10-001不是日期,2023-10-01才是。”) == [“2023-10-01”]
def test_no_dates():
assert extract_dates(“这里没有日期。”) == []
def test_date_like_patterns():
assert extract_dates(“电话是1234-56-7890。”) == [] # 被\b单词边界限制,可能不匹配,取决于上下文。
if __name__ == “__main__”:
pytest.main([“-v”, __file__])
最后,AI清晰地列出了该正则的局限性:
- 有效性验证不足:最大的问题是它无法验证日期是否真实存在(如2023-02-30、2023-11-31)。在生产环境中,提取后必须用
datetime.strptime()或类似库进行验证。 - 格式僵化:它要求月份和日期必须是两位数字(带前导零),
2023-9-5这种格式无法匹配。如果需要更灵活,正则会变复杂。 - 单词边界依赖:
\b在有些上下文(如紧跟标点)下可能工作不如预期。 - 性能考虑:对于极端长的文本,复杂的正则可能有效率问题,但本例中问题不大。
AI不仅完成了代码和测试,还主动“踩坑”,指出了测试用例中暴露出的正则缺陷(匹配了2月30日),并给出了下一步的改进方向。这相当于一份高质量的开发文档和测试报告。
6. 总结与最佳实践建议
通过上面三个案例,我们可以看到,将Qwen2.5-7B-Instruct作为“正则表达式助手”能极大提升效率。它把我们从繁琐的语法记忆和碎片化的调试中解放出来。
回顾一下它的核心优势:
- 自然语言交互:直接用说话的方式提需求,无需记忆复杂语法。
- 逻辑推理能力强:能分析示例、推测规则,甚至发现你需求中潜在的矛盾点。
- 输出结果即用:提供的代码通常结构清晰,附带解释和测试用例,质量很高。
- 考虑边界情况:会主动指出生成的正则的局限性,提醒你注意验证。
在使用过程中,我也总结出一些最佳实践,能让它更好地为你服务:
- 需求描述要具体:越具体,生成的结果越精准。比如,不说“匹配邮箱”,而说“匹配常见的互联网邮箱格式,包含@和点,且域名部分至少有两个字母”。
- 提供正反示例:像案例二那样,提供“应该匹配”和“不应该匹配”的例子,能极大帮助AI理解你的真实意图。
- 明确编程语言和上下文:开头就说明是Python、JavaScript还是其他语言的正则,因为语法略有不同。如果正则是在特定函数或环境中使用,也一并说明。
- 利用多轮对话深化:不要指望一次成功。如果第一版正则不完美,可以把测试结果反馈给AI,比如“这个正则匹配了‘2023-02-30’,但我希望排除无效日期,该怎么修改?” 它能基于上下文进行迭代优化。
- 始终进行人工复核与测试:AI非常强大,但它不是神。对于核心业务逻辑或安全相关的正则(如输入验证),一定要用更全面的测试用例进行最终验证,特别是它提到的那些边界情况。
总而言之,Qwen2.5-7B-Instruct的出现,让处理正则表达式这类“精确但繁琐”的任务,变得像和一个聪明的同事结对编程一样轻松。它负责将模糊的需求转化为精确的语法和代码,而你则专注于更高层的逻辑和业务规则。下次再遇到正则难题,不妨让它来试试。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐




所有评论(0)