;用于加载自定义函数用,切勿删除文件
;新增自定义函数后,需增加相应名称到下列中
;函数名格式必须参照写法


;循环替换
;循环替换直到无匹配时为止
;格式：正则代码框输入:.+ 把全部内容提取出来，替换框输入: 实际正则代码>>替换代码  如：i)cx>>城西
;替换框中的正则代码必须严格按正则书写，不再受软件的忽略大小写影响
;2022.4.28修改ti值可以为空  即由.+$更改为.*$
;=======函数名=======
循环替换(r){
if (Ex正则替换内容="")
	return ""
str:=r[0]
re:=RegExReplace(Ex正则替换内容,">>.*$")
RegExMatch(Ex正则替换内容,"(?<=>>).*$",&ti)
while RegExMatch(str,re)
	str:=RegExReplace(str,re,ti[0])
return str
}

;有人建议userzz保存的操作只能匹配或替换1次。
;于是增加多次执行函数。by 城西 2022.04.24
/*
名称：多次执行
功能：按次序依次多次执行匹配、替换
格式：正则代码框输入:.+ 把全部内容提取出来，替换框输入: 
m：\d+>>次数>>分组号>>连接符  如：i)cx>>-1>>1>>+   
r：\d+>>替换内容>>次数  如：i)cx>>城西>>10  
每组用换行符连接如：
========以下在替换框中输入=============
m:\w>>-1>>>>+
r:\d+>>数字>>-1
r:.+>>($0)
======================================
替换框中的正则代码必须严格按正则书写，不再受软件的忽略大小写、匹配次数、连接符号等影响
*/
;=======函数名=======
多次执行(r){
    if (Ex正则替换内容="")
      return "格式不对,检测重新输入"
    str:=r[0]
    ostr:=""
    re:=Ex正则替换内容
    re:=RegExReplace(re,"(\n){2,}","$1")    ;去除到多余\n
    re:=RegExReplace(re,"^\n+")
    re:=RegExReplace(re,"\n+$")
    if !(re~="i)^((?:m|r)[:：][^\n]+)(\n(?1))*$")   ;如果格式不对，则退出
        return "格式不对,检测重新输入"
    zzarr:=[]
    zzarr:=StrSplit(re,"`n","`r")   ;按换行分组
    strarr:=[]
    loop zzarr.length
    {
        if (zzarr[a_index]~="i)^m")
        {
            zzdmarr:=[]
            v:=RegExReplace(zzarr[a_index],"i)^m[:：]")
            zzdmarr:=StrSplit(v,">>")     ;匹配：^\d{13,}>>-1>>0>>link       格式：正则代码>>匹配次数>> 
            zzdmarr.length:=4
            zzdmarr[2]:=(zzdmarr[2]~="^$|^\D+$") ? -1 : zzdmarr[2]
            zzdmarr[3]:=zzdmarr[3]="" ? 0 : zzdmarr[3]
            strarr:=RegExMatchAll(str,zzdmarr[1],zzdmarr[2],zzdmarr[3])
            if strarr=""
                continue
            str:=strarr[1]
            loop strarr.length - 1
                str.=zzdmarr[4] . strarr[a_index + 1]
        }
        else
        {
            zzdmarr:=[]
            v:=RegExReplace(zzarr[a_index],"i)^r[:：]")
            zzdmarr:=StrSplit(v,">>")     ;替换：^\d{13}>>haha>>-1       格式 
            zzdmarr.length:=3
            zzdmarr[3]:=(zzdmarr[3]~="^$|^\D+$") ? -1 : zzdmarr[3]
            str:=RegExReplace(str,zzdmarr[1],zzdmarr[2],,zzdmarr[3])
        }
    }
    return str
}

/*
名称：依次顺序执行
功能：按次序依次顺序执行匹配、替换
格式：正则代码框输入:.+ 把全部内容提取出来，替换框输入: 
m：\d+>>次数>>分组号>>连接符  如：i)cx>>-1>>1>>+   ;2022.05.10新增支持\i模式提取次数
r：\d+>>替换内容>>次数  如：i)cx>>城西>>10  
每组用换行符连接如：
========以下在替换框中输入=============
m:\w>>-1>>>>+
r:\d+>>数字>>-1
r:.+>>($0)
======================================
替换框中的正则代码必须严格按正则书写，不再受软件的忽略大小写、匹配次数、连接符号等影响
*/
;=======函数名=======
依次顺序执行(r:=""){
    if (Ex正则替换内容="")
      return "格式不对,检测重新输入"
    str:=r[0]
    re:=Ex正则替换内容
    re:=RegExReplace(re,"(\n){2,}","$1")    ;去除到多余\n
    re:=RegExReplace(re,"^\n+")
    re:=RegExReplace(re,"\n+$")
    if !(re~="i)^((?:m|r)[:：][^\n]+)(\n(?1))*$")   ;如果格式不对，则退出
        return "格式不对,检测重新输入"
    zzarr:=[]
    zzarr:=StrSplit(re,"`n","`r")   ;按换行分组
    strarr:=[]
    outljstr:=""
    lsljstr:=""
    loop zzarr.length
    {
        if (zzarr[a_index]~="i)^m")
        {
            zzdmarr:=[]
            v:=RegExReplace(zzarr[a_index],"i)^m[:：]")
            zzdmarr:=StrSplit(v,">>")     ;匹配：^\d{13,}>>-1>>0>>link       格式：正则代码>>匹配次数>>
            zzdmarr.length:=4
            zzdmarr[2]:=(zzdmarr[2]~="^$|^\D+$") ? -1 : zzdmarr[2]
            ycarrcs:=[]
            ycmtkeystr:=""
            if (zzdmarr[1]~="[\s\S]+?\\i[-\d,，:： ]+$")
            {
                ycarrcs :=StrSplit(zzdmarr[1],"\i")
                ycarrcs.length:=2
                zzdmarr[1]:=ycarrcs[1]
                ycmtkeystr :=ycarrcs[2]
            }
            zzdmarr[3]:=zzdmarr[3]="" ? 0 : zzdmarr[3]
            strarr:=RegExMatchAll(str,zzdmarr[1],zzdmarr[2],zzdmarr[3])
            if strarr=""
                continue
            ycmtkeyarr:=GetMatchValueKeyDic(ycmtkeystr,strarr.length)
            if (ycmtkeyarr="")
            {
                lsljstr:=strarr[1]
                loop strarr.length - 1
                    lsljstr.=zzdmarr[4] . strarr[a_index + 1]  
            }
            Else
            {
                lsljstr:=strarr[ycmtkeyarr[1]]
                loop ycmtkeyarr.length -1
                    lsljstr .= zzdmarr[4] . strarr[ycmtkeyarr[A_index + 1]]
            }
        }
        else
        {
            zzdmarr:=[]
            v:=RegExReplace(zzarr[a_index],"i)^r[:：]")
            zzdmarr:=StrSplit(v,">>")     ;替换：^\d{13}>>haha>>-1       格式 
            zzdmarr.length:=3
            zzdmarr[3]:=(zzdmarr[3]~="^$|^\D+$") ? -1 : zzdmarr[3]
            ;str:=RegExReplace(str,zzdmarr[1],zzdmarr[2],,zzdmarr[3])
            lsljstr:=RegExReplace(str,zzdmarr[1],zzdmarr[2],,zzdmarr[3])
        }
        if (a_index !=1)      ;为了避免为空时  不能反映出来
            outljstr .=ExRegExLinkF . lsljstr
        else
            outljstr :=lsljstr
    }
    return outljstr
}

;=======函数名=======
首字母转大写(r:=""){
    if Ex正则表达式:=".+"
        return Regexreplace(r[0],"\b[a-z]",m=>StrUpper(m[0]))
    Else
        return r[0]
}

;=======函数名=======
数字转金额大写(r:=0)
{
    ;从控件中取得数字值
    NumStr:=
	;删除回车
    SmallNum:=r[0]

	NumStr := StrReplace(SmallNum, "`n`r")      ;换行回车
	NumStr := StrReplace(NumStr, "`n")      ;换行
	NumStr := StrReplace(NumStr, "`r")      ;回车
    NumStr := StrReplace(NumStr, "` ")      ;转义字符+半角空格
    NumStr := StrReplace(NumStr, "`　")         ;转义字符+全角空格
    ;删除千位符","
    NumStr := StrReplace(NumStr, ",")
     ;数据是否为数字
     if (RegExMatch(numstr,"^(\-|\+)?\d+(\.\d+)?$")=0)
    {
        ;MsgBox, 48, 提示, 要转换的内容不是数值
        return
    }
    
    numstr:=Round(numstr,2)   ;四舍五入保留2位小数
    
    ;小写转大写的映射数组
    ;NumberArray := Object()
    NumberArray0 := "零"
    NumberArray1 := "壹"
    NumberArray2 := "贰"
    NumberArray3 := "叁"
    NumberArray4 := "肆"
    NumberArray5 := "伍"
    NumberArray6 := "陆"
    NumberArray7 := "柒"
    NumberArray8 := "捌"
    NumberArray9 := "玖"
    ;数位数组
    DigitPlace0 := "元"
    DigitPlace1 := "拾"
    DigitPlace2 := "佰"
    DigitPlace3 := "仟"
    DigitPlace4 := "万"
    DigitPlace5 := "拾"
    DigitPlace6 := "佰"
    DigitPlace7 := "仟"
    DigitPlace8 := "亿"
    DigitPlace9 := "拾"
    DigitPlace10 := "佰"
    DigitPlace12 := "仟"
    DigitPlace13 := "万"
    ;币值
    Valuta0 := "元"
    Valuta1 := "角"
    Valuta2 := "分"
    ;小数点前
    ;StrBeforeRadix :="人民币 "
    StrBeforeRadix :=""
    ;小数点后
    StrAfterRadix :=""
    ;整
    zheng :="整"
    ;需要用到的模式匹配
    StrPattern :=""
    ;临时用变量
    TempStr1 :=""
    TempStr2 :=""
    i :=0
    ;结果字符串
    TransResult :=""
    
    ;找到小数点位置
    RadixPointLocation:=0
    RadixPointLocation := instr(Numstr,".")
    ;开始转换
    ;先转换小数点后的小数
    If RadixPointLocation = 0
    {
        ;数为整数
        StrAfterRadix := Valuta0 . zheng
    } Else  {
        ;不是整数，先读取小数部分
        TempStr1 := substr(Numstr,RadixPointLocation+1)
        i := 1
        NCount :=strlen(TempStr1)
        loop NCount
        {
            NewID:=substr(TempStr1,i,1)
            StrAfterRadix := StrAfterRadix . NumberArray%NewID% . valuta%i%
            i := i + 1
        }
        ;处理小数的各种特殊情况
        StrAfterRadix := StrReplace(StrAfterRadix, "零分", "整")
        StrAfterRadix := StrReplace(StrAfterRadix, "零角", "零")
        StrAfterRadix := StrReplace(StrAfterRadix, "零零")
        StrAfterRadix := StrReplace(StrAfterRadix, "零整", "整")
        If strlen(StrAfterRadix) = 0 Or strlen(StrAfterRadix) = 2
           StrAfterRadix := StrAfterRadix . "整"
    }
 
    if RadixPointLocation = 0
    {
        count1:=strlen(Numstr)
        TempStr1 := substr(Numstr,1, count1)
    }
    else
    {
        TempStr1 := substr(Numstr,1, RadixPointLocation-1)
    }
 
    ;If strlen(TempStr1) > 13   Return "数字太大，本程序无法转换" . numstr
    i := strlen(TempStr1) - 1
    j :=1
        MCount :=strlen(TempStr1)
        loop MCount
        {
            NewID:=substr(TempStr1,j,1)
            StrBeforeRadix := StrBeforeRadix . NumberArray%NewID% . Digitplace%i%
            i := i- 1
            j := j+1
        }
    StrBeforeRadix := StrReplace(StrBeforeRadix, "零拾", "零")
    StrBeforeRadix := StrReplace(StrBeforeRadix, "零佰", "零")
    StrBeforeRadix := StrReplace(StrBeforeRadix, "零仟", "零")
    transresult := StrBeforeRadix . StrAfterradix
    ;MsgBox %transresult%
    ;处理多个0的情况
    findzero := False
    mystr  := ""
    TempStr2 := ""
    i :=1
    NNCount :=strlen(transresult)
    loop NNCount
    {
        TempStr1:=substr(transresult,i,1)
        If (TempStr1 = "零")
            {
                findzero := True
                mystr := ""
            }  Else {
                If findzero
                {
                    mystr := "零" . TempStr1
                    findzero := False
                } Else {
                    mystr := TempStr1
                }
            }
        TempStr2 :=TempStr2 . mystr
        i+=1
    }
 
    TempStr2 := StrReplace(TempStr2, "零万", "万")
    TempStr2 := StrReplace(TempStr2, "零亿", "亿")
    TempStr2 := StrReplace(TempStr2, "零元", "元")
	TempStr2 := StrReplace(TempStr2, "元元", "元")
    transresult := TempStr2
    ;MsgBox %transresult%
    Return (transresult="元整") ? "零元整" : transresult
}

;=======函数名=======
添加序号(str:=""){
    static n2:=0,adr:=""
    global NewAddressStr
    if (adr != NewAddressStr)
    {
        adr:=NewAddressStr
        n2:=0
    }
    n2:=n2+1
    if (str[0] ~="^\d+$")
        return n2  
    try 
    {
        return n2 . str[1]
    }
    catch
    {
        return n2 . str[0]
    }
}

;=======函数名=======
字母转大写(r:="") => StrUpper(r[0])

;=======函数名=======
B64加密(r:="") => StrReplace(b64Encode(r[0]),"`r`n")

;=======函数名=======
B64解密(r:="") => b64Decode(r[0])

;=======函数名=======
汉字转拼音(Text:=""){
    str:=py.allspell(Text[0])
    str:=(str != "") ? str " " : Text[0]
    return str
}
;==================================汉字转拼音V2库===================================
class py
{
    static LOG4AHK_G_MY_DLL_USE_MAP := Map("cpp2ahk.dll" ,Map("chinese_convert_pinyin_initials" , 0, "chinese_convert_pinyin_allspell" , 0,"chinese_convert_pinyin_allspell_muti" , 0, "chinese_convert_pinyin_initials_muti" , 0), "is_load" ,0)
    static is_dll_load := false
    static _ := this.log4ahk_load_all_dll_path()
    static log4ahk_load_all_dll_path()
    {
        SplitPath(A_LineFile, , &dir)
        path := ""
        lib_path := dir
        if(A_IsCompiled)
        {
            path := A_PtrSize == 4 ? A_ScriptDir . "\lib\dll_32\" : A_ScriptDir . "\lib\dll_64\"
            lib_path := A_ScriptDir . "\lib"
        }
        else
        {
            path := (A_PtrSize == 4) ? dir . "\dll_32\" : dir . "\dll_64\"
        }
        dllcall("SetDllDirectory", "Str", path)
        for k,v in this.LOG4AHK_G_MY_DLL_USE_MAP
        {
            if Type(v) ="Map"
            {
                for k1, v1 in v 
                {
                    this.LOG4AHK_G_MY_DLL_USE_MAP[k][k1] := DllCall("GetProcAddress", "Ptr", DllCall("LoadLibrary", "Str", k, "Ptr"), "AStr", k1, "Ptr")
                }
            }
        }
        this.is_dll_load := true
    }
    static allspell(in_str)   ;全拼   单
    {
        if(this.is_dll_load == false)
        {
            this.log4ahk_load_all_dll_path()
        }
        out_str := ""
        out_str := Buffer(0)
        out_str := Buffer(4000)

        py_StrPutVar(in_str, &buf, "CP0")
        rtn := DllCall(this.LOG4AHK_G_MY_DLL_USE_MAP["cpp2ahk.dll"]["chinese_convert_pinyin_allspell"],"Ptr", buf, "Ptr", out_str,"Cdecl Int")
        rtn := StrGet(out_str, 4000,"UTF-8")
        return rtn
    }
    static allspell_muti(in_str)    ;多音 全拼
    {
        if(this.is_dll_load == false)
        {
            this.log4ahk_load_all_dll_path()
        }
        out_str := ""
        out_str := Buffer(0)
        out_str := Buffer(4000)

        py_StrPutVar(in_str, &buf, "UTF-16")
        rtn := DllCall(this.LOG4AHK_G_MY_DLL_USE_MAP["cpp2ahk.dll"]["chinese_convert_pinyin_allspell_muti"],"Ptr", buf, "Ptr", out_str,"Cdecl Int")
        rtn := StrGet(out_str, 4000,"UTF-8")
        return rtn
    }
    static initials_muti(in_str)    ;首字母 全拼
    {
        if(this.is_dll_load == false)
        {
            this.log4ahk_load_all_dll_path()
        }
        out_str := ""
        out_str := Buffer(0)
        out_str := Buffer(4000)

        py_StrPutVar(in_str, &buf, "UTF-16")
        rtn := DllCall(this.LOG4AHK_G_MY_DLL_USE_MAP["cpp2ahk.dll"]["chinese_convert_pinyin_initials_muti"],"Ptr", buf, "Ptr", out_str,"Cdecl Int")
        rtn := StrGet(out_str, 4000,"UTF-8")
        return rtn
    }
    static initials(in_str)         ;首字母  单
    {
        if(this.is_dll_load == false)
        {
            this.log4ahk_load_all_dll_path()
        }
        out_str := ""
        out_str := Buffer(0)
        out_str := Buffer(4000)

        py_StrPutVar(in_str, &buf, "CP0")
        rtn := DllCall(this.LOG4AHK_G_MY_DLL_USE_MAP["cpp2ahk.dll"]["chinese_convert_pinyin_initials"],"Ptr", buf, "Ptr", out_str,"Cdecl Int")
        rtn := StrGet(out_str, 4000,"UTF-8")
        return rtn
    }
}
py_StrPutVar(string, &var, encoding)
{
    var := Buffer(StrPut(string, encoding)*((encoding="utf-16"||encoding="cp1200") ? 2 : 1))
    return StrPut(string, var, encoding)
}

;参考js的写法，测试用
;=======函数名=======
身份证校验测试(r:="")
{
    static 省组:=[]
    sum:=""
    省:="
    (
		,,,,,,,,,,
    北京市,天津市,河北省,山西省,内蒙古自治区,,,,,,
    辽宁省,吉林省,黑龙江省,,,,,,,,
    上海市,江苏省,浙江省,安徽省,福建省,江西省,山东省,,,,
    河南省,湖北省,湖南省,广东省,广西壮族自治区,海南省,,,, 
    重庆市,四川省,贵州省,云南省,西藏自治区,,,,,,,
    陕西省,甘肃省,青海省,宁夏回族自治区,新疆维吾尔自治区
    )"
        ID:=Regexreplace(r[0],"[^\dxX]+")
		if !省组.length
			省组:=StrSplit(省,",")
    地址:=Trim(省组[substr(ID,1,2)]," `t`r`n")
    性别:=Mod(substr(ID,-2,1),2) ? "男" : "女" 
    出生:=substr(ID,7,8)
    出生 := DateDiff(出生, a_now, "days")
    年龄 := 出生<0 ? substr(a_now,1,4)-substr(ID,7,4)+1 : ""
    loop Parse "7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2",","
        Sum:=A_LoopField*SubStr(ID, a_index, 1)+(a_index=1 ? 0 : Sum)
    return  SubStr("10x98765432", Mod(Sum,11)+1, 1)=SubStr(ID, -1) and 年龄 and 地址 
            ? 地址 年龄 "岁" 性别 : "号码错误"
}

;=======函数名=======
英文字符转中文(r:=""){
    s:=r[0]
    s:=StrReplace(s,"!","！")
    s:=StrReplace(s,'"',"“")
    ;s:=StrReplace(s,"$","￥")
    s:=StrReplace(s,"'","’")
    s:=StrReplace(s,"(","（")
    s:=StrReplace(s,")","）")
    s:=StrReplace(s,",","，")
    s:=StrReplace(s,".","。")
    s:=StrReplace(s,":","：")
    s:=StrReplace(s,";","；")
    s:=StrReplace(s,"<","《")
    s:=StrReplace(s,">","》")
    s:=StrReplace(s,"?","？")
    ;s:=StrReplace(s,"\","、")
    s:=StrReplace(s,"[","【")
    s:=StrReplace(s,"]","】")
    ;s:=StrReplace(s,"^","……")
  return s
}

;=======函数名=======
中文字符转英文(r:=""){
    s:=r[0]
    s:=StrReplace(s,"！","!")
    s:=StrReplace(s,"“",'"')
    ;s:=StrReplace(s,"￥","$")
    s:=StrReplace(s,"’","'")
    s:=StrReplace(s,"（","(")
    s:=StrReplace(s,"）",")")
    s:=StrReplace(s,"，",",")
    s:=StrReplace(s,"。",".")
    s:=StrReplace(s,"：",":")
    s:=StrReplace(s,"；",";")
    s:=StrReplace(s,"《","<")
    s:=StrReplace(s,"》",">")
    s:=StrReplace(s,"？","?")
    ;s:=StrReplace(s,"、","\")
    s:=StrReplace(s,"【","[")
    s:=StrReplace(s,"】","]")
    ;s:=StrReplace(s,"……","^")
  return s
}

;=======函数名=======
简体转繁体(r:="") => aardio.onjt2ft(r[0])

;=======函数名=======
繁体转简体(r:="") => aardio.onft2jt(r[0])

;=======函数名=======
中文分词(r:="") => aardio.onzwfc(r[0])

;=======函数名=======
数字运算(r:=""){
    re:=Ex正则替换内容
    if !(re~="\$(\d+)")
        return
    RegExMatch(re,"\$(\d+)",&ot)
    try
        s:=r[ot[1]]
    catch
        s:=""
    s:=StrReplace(re,"$" ot[1],s)
    s:=aardio.oneval(s)
    return s
}

