递归火山软件开发平台

标题: 正则表达式类 [打印本页]

作者: 小蜗牛    时间: 2024-10-30 15:00
标题: 正则表达式类
由于官方库创建后,使用匹配并非线程安全..因此重新封装一遍..
封装方式参考了易语言~并添加了一个自定义替换~


(, 下载次数: 3)

<火山程序 类型 = "通常" 版本 = 1 />

类 正则匹配选项 <公开 注释 = "提供正则匹配过程中所欲使用的各种选项,支持多个值组合使用." 折叠 @常量类 = 整数>
{
    常量 默认 <公开 值 = @"@std::regex_constants::match_flag_type::match_default" 注释 = "使用默认选项"
            编辑时信息 = "0, B2217, 0, 0">
    常量 非行首 <公开 值 = @"@std::regex_constants::match_flag_type::match_not_bol" 注释 = "不将首字符作为行首处理"
            编辑时信息 = "0, B2217, 0, 0">
    常量 非行尾 <公开 值 = @"@std::regex_constants::match_flag_type::match_not_eol" 注释 = "不将尾字符作为行尾处理"
            编辑时信息 = "0, B2217, 0, 0">
    常量 非单词首 <公开 值 = @"@std::regex_constants::match_flag_type::match_not_bow" 注释 = "不将首字符作为单词首处理"
            编辑时信息 = "0, B2217, 0, 0">
    常量 非单词尾 <公开 值 = @"@std::regex_constants::match_flag_type::match_not_eow" 注释 = "不将尾字符作为单词尾处理"
            编辑时信息 = "0, B2217, 0, 0">
    常量 任意匹配 <公开 值 = @"@std::regex_constants::match_flag_type::match_any" 注释 = "如果存在多于一个匹配,则接受任何匹配项."
            编辑时信息 = "0, B2217, 0, 0">
    常量 非空匹配 <公开 值 = @"@std::regex_constants::match_flag_type::match_not_null" 注释 = "不匹配任何空序列"
            编辑时信息 = "0, B2217, 0, 0">
    常量 连续匹配 <公开 值 = @"@std::regex_constants::match_flag_type::match_continuous" 注释 = "子匹配组必须从要匹配的第一个字符开始"
            编辑时信息 = "0, B2217, 0, 0">
    常量 包含之前 <公开 值 = @"@std::regex_constants::match_flag_type::match_prev_avail"
            注释 = "在表达式第一个字符之前还存在有其他任意字符" 编辑时信息 = "0, B2217, 0, 0">
}

类 正则表达式搜索选项 <公开 注释 = "提供正则表达式所欲使用的选项,支持多个值组合使用." 折叠 @常量类 = 整数>
{
    常量 不区分大小写 <公开 值 = @"@std::regex_constants::syntax_option_type::icase" 注释 = "在匹配过程中忽略大小写"
            编辑时信息 = "0, 236643, 0, 0">
    常量 无子匹配组 <公开 值 = @"@std::regex_constants::syntax_option_type::nosubs" 注释 = "表示匹配后不保存子匹配组的数据"
            编辑时信息 = "0, 236643, 0, 0">
    常量 匹配效率优先 <公开 值 = @"@std::regex_constants::syntax_option_type:ptimize" 注释 = "执行速度优先于构造速度"
            编辑时信息 = "0, 236643, 0, 0">
    常量 字符范围 <公开 值 = @"@std::regex_constants::syntax_option_type::collate" 注释 = "指定表达式是否支持使用字符范围,例如\"a-z\"."
            编辑时信息 = "0, 236643, 0, 0">
    常量 ECMA语法 <公开 值 = @"@std::regex_constants::syntax_option_type::ECMAScript" 注释 = "指定表达式使用ECMA-262指定的语法"
            编辑时信息 = "0, 236643, 0, 0">
    常量 基本语法 <公开 值 = @"@std::regex_constants::syntax_option_type::basic" 注释 = "指定表达式使用POSIX基本的正则表达式语法"
            编辑时信息 = "0, 236643, 0, 0">
    常量 扩展语法 <公开 值 = @"@std::regex_constants::syntax_option_type::extended" 注释 = "指定表达式使用POSIX拓展的正则表达式语法"
            编辑时信息 = "0, 236643, 0, 0">
    常量 AWK语法 <公开 值 = @"@std::regex_constants::syntax_option_type::awk" 注释 = "指定表达式使用POSIX版本的awk语言正则表达式语法"
            编辑时信息 = "0, 236643, 0, 0">
    常量 GREP语法 <公开 值 = @"@std::regex_constants::syntax_option_type::grep"
            注释 = "指定表达式使用POSIX版本的grep语言正则表达式语法" 编辑时信息 = "0, 236643, 0, 0">
    常量 EGREP语法 <公开 值 = @"@std::regex_constants::syntax_option_type::egrep"
            注释 = "指定表达式使用POSIX版本的egrep语言正则表达式语法">
}

类 正则表达式类 <公开 折叠 @别名 = "std::wregex" @别名类型 = 本地类 @视窗.外部头文件 = "<regex>">
{
    方法 创建 <公开 静态 类型 = 逻辑型 注释 = "如果为 全局变量/静态变量 创建并非线程安全~" 编辑时信息 = "48884, 0, 0, 0" @禁止流程检查 = 真>
    参数 当前对象 <类型 = 正则表达式类 编辑时信息 = "48884, 0, 0, 0">
    参数 表达式 <类型 = 文本型 编辑时信息 = "48884, 0, 0, 0">
    参数 表达式选项 <类型 = 正则表达式搜索选项 注释 = "提供所欲使用的表达式内容选项,请参考\"正则表达式选项\"所提供的常量值,可单个或多个值组合使用. 正则表达式搜索选项.ECMA语法"
            编辑时信息 = "48884, 0, 0, 0" @默认值 = 正则表达式搜索选项.不区分大小写>
    {
        开始俘获异常 ()
        {
            @ @<当前对象> = std::wregex(@<表达式>.GetText(), (std::regex_constants::syntax_option_type)@<表达式选项>);
            返回 (真)
        }
        俘获所有异常 ()
        {
            返回 (假)
        }
    }

    方法 正则分割 <公开 静态 类型 = 文本标准数组类 注释 = "线程安全" 折叠>
    参数 当前对象 <类型 = 正则表达式类>
    参数 欲匹配内容 <类型 = 文本型 注释 = "提供所欲进行匹配的文本内容">
    参数 匹配选项 <类型 = 正则匹配选项 注释 = "提供所欲使用的匹配选项,请参考\"正则匹配选项\"所提供的常量值,可单个或多个值组合使用." @默认值 = 正则匹配选项.默认>
    {
        变量 当前结果 <类型 = 正则搜索结果>
        变量 结果文本 <类型 = 文本型>
        变量 上一个结果 <类型 = 正则搜索结果>
        变量 字符数 <类型 = 整数>
        变量 返回数组 <类型 = 文本标准数组类>
        如果 (当前对象.搜索 (欲匹配内容, 匹配选项, 当前结果))
        {
            如果 (当前结果.取开始搜索文本指针 () != 取文本指针 (欲匹配内容))  // 前面有非匹配数据!
            {
                清空文本 (结果文本)
                添加部分文本指针内容 (结果文本, 取文本指针 (欲匹配内容), (整数)(当前结果.取开始搜索文本指针 () - 取文本指针 (欲匹配内容)) / 2)
                返回数组.加入成员 (结果文本)
            }

            上一个结果 = 当前结果
            判断循环 (当前对象.继续搜索 (匹配选项, 当前结果))
            {
                如果 (当前结果.取开始搜索文本指针 () != 上一个结果.取剩余搜索文本指针 ())  // 前面有非匹配数据!
                {
                    清空文本 (结果文本)
                    字符数 = (整数)(当前结果.取开始搜索文本指针 () - 上一个结果.取剩余搜索文本指针 ()) / 2
                    添加部分文本指针内容 (结果文本, 上一个结果.取剩余搜索文本指针 (), 字符数)
                    返回数组.加入成员 (结果文本)
                }

                上一个结果 = 当前结果
            }

            如果 (上一个结果.取剩余搜索文本指针 () != 0 && 读指针处值 (上一个结果.取剩余搜索文本指针 (), 字符) != '\0')  // 后面还有非匹配的数据要添加!
            {
                清空文本 (结果文本)
                字符数 = (整数)(当前结果.取开始搜索文本指针 () - 上一个结果.取剩余搜索文本指针 ()) / 2
                添加部分文本指针内容 (结果文本, 上一个结果.取剩余搜索文本指针 (), 字符数)
                返回数组.加入成员 (结果文本)
            }
        }


        返回 (返回数组)

    }

    方法 是否完全匹配 <公开 静态 类型 = 逻辑型 注释 = "线程安全" @嵌入式方法 = "">
    参数 当前对象 <类型 = 正则表达式类>
    参数 欲匹配内容 <类型 = 文本型 注释 = "提供所欲进行匹配的文本内容">
    参数 匹配选项 <类型 = 正则匹配选项 注释 = "提供所欲使用的匹配选项,请参考\"正则匹配选项\"所提供的常量值,可单个或多个值组合使用." @默认值 = 正则匹配选项.默认>
    {
        @ std::regex_match(@<欲匹配内容>.GetText(), @<当前对象>, (std::regex_constants::match_flag_type)@<匹配选项>);
    }

    方法 替换 <公开 静态 类型 = 文本型 注释 = "线程安全" 折叠 @嵌入式方法 = "">
    参数 当前对象 <类型 = 正则表达式类>
    参数 欲替换内容 <类型 = 文本型 注释 = "提供所欲进行匹配的文本内容">
    参数 替换为内容 <类型 = 文本型 注释 = "提供所欲使用的替换格式内容">
    参数 匹配选项 <类型 = 正则匹配选项 注释 = "提供所欲使用的匹配选项,请参考\"正则匹配选项\"所提供的常量值,可单个或多个值组合使用." @默认值 = 正则匹配选项.默认>
    {
        @ CVolString(std::regex_replace(@<欲替换内容>.GetText(), 当前对象, @<替换为内容>.GetText(), (std::regex_constants::match_flag_type)@<匹配选项>))
    }

    方法 替换全部 <公开 静态 类型 = 文本型 注释 = "线程安全" 折叠>
    参数 当前对象 <类型 = 正则表达式类>
    参数 欲替换内容 <类型 = 文本型 注释 = "提供所欲进行匹配的文本内容">
    参数 替换为内容 <类型 = 文本型 注释 = "提供所欲使用的替换格式内容">
    参数 匹配选项 <类型 = 正则匹配选项 注释 = "提供所欲使用的匹配选项,请参考\"正则匹配选项\"所提供的常量值,可单个或多个值组合使用." @默认值 = 正则匹配选项.默认>
    {
        返回 (当前对象.自定义替换 (欲替换内容, 取静态方法地址 (自定义替换_全部替换), 取文本指针 (替换为内容), 匹配选项))
    }

    方法 自定义替换 <公开 静态 类型 = 文本型 注释 = "线程安全" 折叠>
    参数 当前对象 <类型 = 正则表达式类>
    参数 欲替换内容 <类型 = 文本型 注释 = "提供所欲进行匹配的文本内容">
    参数 替换回调函数 <类型 = 变整数 注释 = "参考 \"自定义替换回调函数模板()\"">
    参数 回调函数参数 <类型 = 变整数>
    参数 匹配选项 <类型 = 正则匹配选项 注释 = "提供所欲使用的匹配选项,请参考\"正则匹配选项\"所提供的常量值,可单个或多个值组合使用." @默认值 = 正则匹配选项.默认>
    {
        变量 当前结果 <类型 = 正则搜索结果>
        变量 替换为文本 <类型 = 文本型>
        变量 结果文本 <类型 = 文本型>
        变量 上一个结果 <类型 = 正则搜索结果>
        变量 字符数 <类型 = 整数>
        如果 (当前对象.搜索 (欲替换内容, 匹配选项, 当前结果))
        {
            置文本预分配字符数 (结果文本, 取文本长度 (欲替换内容))

            如果 (当前结果.取开始搜索文本指针 () != 取文本指针 (欲替换内容))  // 前面有非匹配数据!
            {
                添加部分文本指针内容 (结果文本, 取文本指针 (欲替换内容), (整数)(当前结果.取开始搜索文本指针 () - 取文本指针 (欲替换内容)) / 2)
            }

            如果 (调用静态方法 (替换回调函数, 逻辑型, 回调函数参数, 当前结果, 取变量地址 (替换为文本)) == 真)
            {
                加入文本 (结果文本, 替换为文本)
            }
            上一个结果 = 当前结果
            判断循环 (当前对象.继续搜索 (匹配选项, 当前结果))
            {
                如果 (当前结果.取开始搜索文本指针 () != 上一个结果.取剩余搜索文本指针 ())  // 前面有非匹配数据!
                {
                    字符数 = (整数)(当前结果.取开始搜索文本指针 () - 上一个结果.取剩余搜索文本指针 ()) / 2
                    添加部分文本指针内容 (结果文本, 上一个结果.取剩余搜索文本指针 (), 字符数)
                }

                清空文本 (替换为文本)
                如果 (调用静态方法 (替换回调函数, 逻辑型, 回调函数参数, 当前结果, 取变量地址 (替换为文本)) == 真)
                {
                    加入文本 (结果文本, 替换为文本)
                }
                上一个结果 = 当前结果
            }

            如果 (上一个结果.取剩余搜索文本指针 () != 0 && 读指针处值 (上一个结果.取剩余搜索文本指针 (), 字符) != '\0')  // 后面还有非匹配的数据要添加!
            {
                添加文本指针内容 (结果文本, 上一个结果.取剩余搜索文本指针 ())
            }
        }
        否则
        {
            返回 (欲替换内容)  // 匹配失败 直接返回原文本
        }

        返回 (结果文本)
    }

    方法 搜索 <公开 静态 类型 = 逻辑型 注释 = "线程安全 搜索第一个匹配结果!" 折叠 @嵌入式方法 = "">
    参数 当前对象 <类型 = 正则表达式类>
    参数 要搜索的文本 <类型 = 文本型>
    参数 匹配选项 <类型 = 正则匹配选项 注释 = "提供所欲使用的匹配选项,请参考\"正则匹配选项\"所提供的常量值,可单个或多个值组合使用." @默认值 = 正则匹配选项.默认>
    参数 返回搜索结果 <类型 = 正则搜索结果>
    {
        @ std::regex_search(@<要搜索的文本>.GetText(), @<返回搜索结果>, @<当前对象>, (std::regex_constants::match_flag_type)@<匹配选项>)
    }

    方法 继续搜索 <公开 静态 类型 = 逻辑型 注释 = "线程安全 使用方法,参考 \"搜索全部\"" 返回值注释 = "如果存在下一个匹配文本段将返回真,否则返回假." 折叠 @禁止流程检查 = 真>
    参数 当前对象 <类型 = 正则表达式类>
    参数 匹配选项 <类型 = 正则匹配选项 注释 = "提供所欲使用的匹配选项,请参考\"正则匹配选项\"所提供的常量值,可单个或多个值组合使用." @默认值 = 正则匹配选项.默认>
    参数 返回搜索结果 <类型 = 正则搜索结果>
    {
        @ return std::regex_search(@<返回搜索结果>[0].second, @<返回搜索结果>,@<当前对象>, (std::regex_constants::match_flag_type)@<匹配选项>);
    }

    方法 搜索全部 <公开 静态 类型 = 正则搜索结果数组 注释 = "线程安全" 折叠>
    参数 当前对象 <类型 = 正则表达式类>
    参数 要匹配的文本 <类型 = 文本型>
    参数 匹配选项 <类型 = 正则匹配选项 注释 = "提供所欲使用的匹配选项,请参考\"正则匹配选项\"所提供的常量值,可单个或多个值组合使用." @默认值 = 正则匹配选项.默认>
    {
        变量 返回数组 <类型 = 正则搜索结果数组>
        变量 结果 <类型 = 正则搜索结果>
        返回数组.删除所有成员 ()
        如果 (当前对象.搜索 (要匹配的文本, 匹配选项, 结果))
        {
            返回数组.加入成员 (结果)
            判断循环 (当前对象.继续搜索 (匹配选项, 结果))
            {
                返回数组.加入成员 (结果)
            }
        }
        返回 (返回数组)

    }

    方法 自定义替换回调函数模板 <静态 类型 = 逻辑型 返回值注释 = "真=替换 假=不替换!" 折叠>
    参数 回调参数 <类型 = 变整数>
    参数 当前匹配结果 <类型 = 正则搜索结果>
    参数 返回替换为内容 <类型 = 文本型 注释 = "置文本(返回替换为内容, xxxx)">
    {
        返回 (真)
    }

    方法 自定义替换_全部替换 <静态 类型 = 逻辑型 返回值注释 = "真=替换 假=不替换!" 折叠>
    参数 回调参数 <类型 = 变整数>
    参数 当前匹配结果 <类型 = 正则搜索结果>
    参数 返回替换为内容 <类型 = 文本型 注释 = "置文本(返回替换为内容, xxxx)">
    {
        清空文本 (返回替换为内容)
        添加文本指针内容 (返回替换为内容, 回调参数)
        返回 (真)
    }
}

类 正则搜索结果数组 <公开 基础类 = 标准数组模板类 @模板实现类 = "正则搜索结果">

类 正则搜索结果 <公开 折叠 @别名 = "std::wcmatch" @别名类型 = 本地类>
{
    方法 清空 <公开 静态 注释 = "清空搜索结果" 折叠 @嵌入式方法 = "">
    参数 当前对象 <类型 = 正则搜索结果>
    {
        @ @<当前对象> = std::wcmatch() // 重置为默认状态
    }

    方法 取子匹配文本 <公开 静态 类型 = 文本型 注释 = "使用\"匹配\"方法后获取所匹配到的子匹配内容" 折叠 @禁止流程检查 = 真>
    参数 当前对象 <类型 = 正则搜索结果>
    参数 子匹配索引 <类型 = 整数 注释 = "提供所欲获取子匹配内容的索引位置,0表示获取整个匹配组内容,从1开始获取子匹配组内容.">
    {
        @ return CVolString(@<当前对象>.str(@<子匹配索引>).c_str());
    }

    方法 取子匹配文本指针 <公开 静态 类型 = 变整数 注释 = "使用\"匹配\"方法后获取所匹配到的子匹配内容" 折叠 @嵌入式方法 = "">
    参数 当前对象 <类型 = 正则搜索结果>
    参数 子匹配索引 <类型 = 整数 注释 = "提供所欲获取子匹配内容的索引位置,0表示获取整个匹配组内容,从1开始获取子匹配组内容.">
    {
        @ (INT_P)@<当前对象>.str(@<子匹配索引>).c_str())
    }

    方法 取子匹配文本长度 <公开 静态 类型 = 整数 折叠 @禁止流程检查 = 真>
    参数 当前对象 <类型 = 正则搜索结果>
    参数 子匹配索引 <类型 = 整数 注释 = "提供所欲获取子匹配内容的索引位置,0表示获取整个匹配组内容,从1开始获取子匹配组内容.">
    {
        @ return (INT)(@<当前对象>[@<子匹配索引>].second - @<当前对象>[@<子匹配索引>].first);
    }

    方法 取开始搜索文本指针 <公开 静态 类型 = 变整数 折叠 @嵌入式方法 = "">
    参数 当前对象 <类型 = 正则搜索结果>
    {
        @ (INT_P)@<当前对象>[0].first
    }

    方法 取剩余搜索文本指针 <公开 静态 类型 = 变整数 折叠 @嵌入式方法 = "">
    参数 当前对象 <类型 = 正则搜索结果>
    {
        @ (INT_P)@<当前对象>[0].second
    }

    方法 取子匹配数量 <公开 静态 类型 = 整数 注释 = "使用\"匹配\"方法后获取子匹配数量" 折叠 @嵌入式方法 = "">
    参数 当前对象 <类型 = 正则搜索结果>
    {
        @ (INT)@<当前对象>.size()
    }

    方法 是否为空 <公开 静态 类型 = 逻辑型 注释 = "检查上次执行\"匹配\"是否匹配到内容." 返回值注释 = "匹配到内容返回真,否则返回假." 折叠 @嵌入式方法 = "">
    参数 当前对象 <类型 = 正则搜索结果>
    {
        @ @<当前对象>.empty()
    }
}







欢迎光临 递归火山软件开发平台 (https://bbs.voldp.com/) Powered by Discuz! X3.4