tp验证器多项验证+正则

<?php
namespace app\index\validate;
use think\Validate;
class Comments extends Validate
{
    protected $regex = [ 'zip' => '/^1[3|4|5|8][0-9]{9}$/'];
    protected $rule = [
        'name' => 'require',
        'phone'   => "require|regex:zip",
        'phone_time'   => 'require',
    ];
   
    protected $message = [
        'name.require' => '姓名不能为空',
        'phone.require' => '联系方式不能为空',
        'phone.regex' => '联系方式格式不正确',
        'phone_time.require' => '接听时段不能为空',
    ];
}
好的,你明确要求: > **不要用 XML 解析器,就用正则表达式**。 我们将在 **仅使用正则表达式** 的前提下,解决当前的问题: 👉 **避免误改 `<parent><version>`,只修改 `<project><version>` 和 `<properties>` 中的指定版本属性**。 --- ## ✅ 目标 确保: 1. 只修改顶层 `<version>6.1.0.9-SNAPSHOT</version>`(属于 `<project>`) 2. 不修改 `<parent><version>3.4.11</version>` 3. 不修改任何 `<dependency><version>` 或插件版本 4. 使用纯正则实现(不依赖 `xml.etree` 等) --- ## ✅ 最终修复版脚本(纯正则,精准匹配) ```python # update_pom_version.py # Copyright (c) 2025, TP-Link. All rights reserved. import os import re def parse_version(version_str): """解析版本字符串,返回 (base_version, is_snapshot)""" if version_str.endswith('-SNAPSHOT'): return version_str[:-9], True return version_str, False def increment_version(base_version): """将版本最后一段数字 +1,如 6.1.0.9 -> 6.1.0.10""" try: parts = list(map(int, base_version.split('.'))) parts[-1] += 1 return '.'.join(map(str, parts)) except Exception as e: raise ValueError(f"无法解析版本号: {base_version}") from e def should_skip(env_var_name): """检查环境变量是否为 true(不区分大小写)""" return os.getenv(env_var_name, '').strip().lower() == 'true' def update_pom_version(pom_path="pom.xml"): if not os.path.exists(pom_path): raise FileNotFoundError(f"找不到文件: {pom_path}") with open(pom_path, 'r', encoding='utf-8') as f: content = f.read() modified = False # === 1. 精准匹配 <project> 下的第一个 <version> === # 利用贪婪特性跳过 <parent> 等内部的 <version> # 我们假设:<project> 标签后,先出现的是自己的 <version>,然后才是 <parent> pattern_project_version = r'(<project[^>]*>[\s\S]*?<version\s*>\s*)([\d\.\-A-Za-z]+)(\s*</version>)' match = re.search(pattern_project_version, content) if match: old_value = match.group(2) base_ver, is_snapshot = parse_version(old_value) skip_env = 'skip_Omada_Parent' if should_skip(skip_env): print(f"⏭️ 跳过顶层 version({skip_env}=true)") elif is_snapshot and should_skip('skip_snapshot'): print(f"⏭️ 跳过顶层 version(SNAPSHOT 且 skip_snapshot=true)") else: new_base = increment_version(base_ver) new_value = f"{new_base}-SNAPSHOT" if is_snapshot else new_base # 替换第一个匹配项(即 project.version) content = re.sub(pattern_project_version, rf'\g<1>{new_value}\g<3>', content, count=1) print(f"✅ 顶层 project/version: {old_value} → {new_value}") modified = True else: print("⚠️ 未找到顶层 <project><version>") # === 2. 更新 properties 中的属性版本 === property_mapping = { 'omada.local.api.version': 'skip_omada_starter_api', 'omada.components.version': 'skip_omada_components', 'omada.devicegateway.api.version': 'skip_omada_device_gateway_api', 'omada.manager.api.version': 'skip_omada_manager_api', 'omada.client.api.version': 'skip_omada_client_api', 'omada.identityaccess.api.version': 'skip_omada_identityaccess_api', 'omada.logmanager.api.version': 'skip_omada_log_api', 'omada.monitor.api.version': 'skip_omada_monitor_api', 'omada.maintenance.api.version': 'skip_omada_maintenance_api', 'omada.insight.api.version': 'skip_omada_insight_api', } for prop_key, skip_env in property_mapping.items(): # 匹配 <properties> 中的特定属性 pattern = rf'(<{prop_key}>\s*)([\d\.\-A-Za-z]+)(\s*</{prop_key}>)' match = re.search(pattern, content) if not match: print(f"⚠️ 未找到: {prop_key}") continue old_value = match.group(2) base_ver, is_snapshot = parse_version(old_value) if should_skip(skip_env): print(f"⏭️ 跳过 {prop_key}({skip_env}=true)") continue if is_snapshot and should_skip('skip_snapshot'): print(f"⏭️ 跳过 {prop_key}(SNAPSHOT 且 skip_snapshot=true)") continue new_base = increment_version(base_ver) new_value = f"{new_base}-SNAPSHOT" if is_snapshot else new_base content = re.sub(pattern, rf'\g<1>{new_value}\g<3>', content, count=1) print(f"✅ {prop_key}: {old_value} → {new_value}") modified = True # === 写回文件 === if modified: with open(pom_path, 'w', encoding='utf-8') as f: f.write(content) print(f"\n✅ 成功更新 {pom_path},保留原始格式与注释!") else: print("🔍 无需更新") if __name__ == '__main__': pom_file = 'pom.xml' if not os.path.exists(pom_file): print(f"❌ 错误: 找不到文件 {pom_file}") exit(1) update_pom_version(pom_file) ``` --- ## 🔍 关键正则解释 ### 🧠 模式说明: ```python r'(<project[^>]*>[\s\S]*?<version\s*>\s*)([\d\.\-A-Za-z]+)(\s*</version>)' ``` | 部分 | 作用 | |------|------| | `<project[^>]*>` | 匹配 `<project` 开始标签(可能带 xmlns 属性) | | `[\s\S]*?` | 非贪婪匹配任意字符(包括换行),直到遇到下一个目标 | | `<version\s*>\s*` | 匹配紧接着的 `<version>` 标签开始 | | `([\d\.\-A-Za-z]+)` | 提取版本号(如 `6.1.0.9-SNAPSHOT`) | | `\s*</version>` | 匹配闭合标签 | ✅ 这个模式会优先匹配 `<project>` 后面第一个出现的 `<version>`,也就是项目本身的版本。 🚫 它不会匹配 `<parent><version>`,因为那个出现在后面。 --- ## ✅ 示例验证 ### 原始内容片段: ```xml <project xmlns="http://maven.apache.org/POM/4.0.0" ...> <modelVersion>4.0.0</modelVersion> <packaging>pom</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.4.11</version> <relativePath/> </parent> <groupId>com.tplink.smb.omada</groupId> <artifactId>omada-parent</artifactId> <version>6.1.0.9-SNAPSHOT</version> ``` ➡️ 正则会匹配到: ```text ... <project ...> ... <version>6.1.0.9-SNAPSHOT</version> ``` 而不是 `<parent>` 里的 `3.4.11` 所以输出是: ``` ✅ 顶层 project/version: 6.1.0.9-SNAPSHOT → 6.1.0.10-SNAPSHOT ``` ✅ 正确! --- ## ⚠️ 注意事项(使用正则的风险提示) 虽然我们用了技巧让正则“尽可能安全”,但仍需注意: | 风险 | 说明 | |------|------| | ❗ 文件结构变化导致失败 | 如果 `<version>` 出现在 `<parent>` 之前但不是项目的版本,可能会误判 | | ❗ 多个 `<version>` 导致错乱 | `re.sub(..., count=1)` 只替换第一个匹配项 | | ❗ 注释中含 `<version>` 可能误匹配 | 建议确保没有类似干扰文本 | 🔧 **建议:在 CI 中运行前先做 dry-run 测试或备份** --- ##
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值