脚本示例

正则匹配与替换脚本示例

RegExMatch、RegExSplitCapture、RegExReplace 三个正则命令的用法与完整示例。

用途

正则三件套的用法与示例:RegExMatch 检测内容是否匹配(如手机号、网址、颜色码),RegExSplitCapture 分解并捕获匹配串与剩余串,RegExReplace 做正则替换。

参考脚本

  增加正则匹配检测NPC命令:RegExMatch 源字符 匹配表达式    // S1是需要检测的字符串,可以到https://www.jyshare.com/front-end/854/验证
    例:
    ; "1[34578]\d{9}"       // 手机号码
    ; "\$[0-9A-Fa-f]+"      // NPC说话内容里的16进制颜色
    ; 检测查源字符中是否包含有URL
    #if
    ; 检测到内容里有网址
    RegExMatch 源字符 "[a-zA-Z]+:\/\/"
    #act

  增加正则分解捕获NPC命令:RegExSplitCapture 源字符 查找表达式
    匹配的字符串数量在:<$STR(M_MATCHED_CNT)>
    匹配的字符串保存在:<$STR(S_MATCHED_STRS[n]>  // n是数字,在0至“<$STR(M_MATCHED_CNT)> - 1”之间
    分解后剩余的字符串数量在:<$STR(M_SPLIT_CNT)>        // “分解后剩余的字符串”指不包含匹配字符串的剩余部分,比如源字符是:左中右,按表达式“中”分解后,剩余字符串是:左和右(数量2),匹配字符串是:中(数量1)
    分解后剩余的字符串保存在:<$STR(S_SPLIT_STRS[n]> // n是数字,在0至“<$STR(M_SPLIT_CNT)> - 1”之间
    例:
    #act
    ; <$STR(M_MATCHED_CNT)>将等于2
    ; <$STR(S_MATCHED_STRS[0])>将等于:123
    ; <$STR(S_MATCHED_STRS[1])>将等于:456
    ; <$STR(M_SPLIT_CNT)>将等于3
    ; <$STR(S_SPLIT_STRS[0])>将等于:左
    ; <$STR(S_SPLIT_STRS[1])>将等于:中
    ; <$STR(S_SPLIT_STRS[2])>将等于:右
    RegExSplitCapture 左123中456右 [0-9]+

  增加正则替换字符NPC命令:RegExReplace S1 查找表达式 替换字符 替换次数(默认1次)   // 使用正则表达式方式,在S1中按“查找表达式”查找,找到后替换为“替换字符”,结果还是在S1中       // 相关资料可参考https://www.runoob.com/regexp/regexp-tutorial.html
    见下面例子

#if
True
#Act
Mov S11 强化圣战头盔|4,坚硬圣战头盔|5,破魔圣战头盔|6,嗜血圣战头盔|7,+装备碎片|10+原质晶石|0

;替换S11变量的所有|符号为* (强化圣战头盔*4,坚硬圣战头盔*5,破魔圣战头盔*6,嗜血圣战头盔*7,+装备碎片*10+原质晶石*0)

StringReplace S11 | *

;复制S12 S13都为S11的值。方便下面分隔
Mov S12 <$Str(S11)>
Mov S13 <$Str(S11)>

;删除S12 第一个"+"以及后面的所有内容或地S12的内容为 (强化圣战头盔*4,坚硬圣战头盔*5,破魔圣战头盔*6,嗜血圣战头盔*7,)
RegExReplace S12 "[+].*" ""
;获得S12变量的目前字符长度。以便分隔出来后面的S13的内容
GetStrLengTh $Str(S12) M11
;删除S13 从第一个字符到S12的最后一个字符。即得到 S13 的内容为 (+装备碎片*10+原质晶石*0)
Dec S13 1 <$STR(M11)>

;使用"+"号分隔S13的内容.这里要注意的是"[+]"里面的"+"为正常字符。"[+]"后面的+为正则特殊符号。具体使用方法可参照正则说明书。
RegExSplitCapture <$Str(S13)> "[+]+"
;因为第一个"+"号前面没有内容,所以获得以下结果

;<$STR(S_SPLIT_STRS[0])>  = ""

;<$STR(S_SPLIT_STRS[1])>  = 装备碎片*10

;<$STR(S_SPLIT_STRS[2])>  = 原质晶石*0

;<$STR(M_SPLIT_CNT)> = 3

;因为<$STR(M_SPLIT_CNT)>为引擎内置变量。 每次使用正则拆分都会获取不一样的数据。所以这里做下赋值

Mov M数据数量 <$STR(M_SPLIT_CNT)>

;开始倒叙循环。因为<$STR(S_SPLIT_STRS[0])>下标从0开始的。后面又是检测循环次数大于等于0继续循环。 所以这里初始变量为 参数1=M循环次数=3-1 参数2=检测循环次数大于等于0继续循环。 参数3=每次循环 M循环次数减1
#For (M循环次数 = M数据数量 - 1, M循环次数 ? 0, M循环次数 - 1)
#if
True
#Act
Sendmsg 7 需要材料<$LoopCursor>:<$STR(S_SPLIT_STRS[<$LoopCursor>])>

#if
CompVal <$LoopCursor> = 1
#act
;上面说了。因为<$STR(S_SPLIT_STRS[0])>为"" 所以到1的时间输出完。就直接跳出循环
BreakLoop

#~For

#if
True
#Act
;使用","号分隔S12的内容.这里要注意的是"[,]"里面的","为正常字符。"[,]"后面的+为正则特殊符号。具体使用方法可参照正则说明书。
RegExSplitCapture <$Str(S12)> "[,]+"

;因为最后一个个","号前面没有内容,所以获得以下结果

;<$STR(S_SPLIT_STRS[0])>  = 强化圣战头盔*4

;<$STR(S_SPLIT_STRS[1])>  = 坚硬圣战头盔*5

;<$STR(S_SPLIT_STRS[2])>  = 破魔圣战头盔*6

;<$STR(S_SPLIT_STRS[3])>  = 嗜血圣战头盔*7

;<$STR(S_SPLIT_STRS[4])>  = ""

;<$STR(M_SPLIT_CNT)> = 5

;因为已知最后一个","后面是没有数据的。所以为了不输出空的数据。这里可以直接先给数据数量-1
Mov M数据数量 <$STR(M_SPLIT_CNT)>
Dec M数据数量 1

;开始正序循环。因为<$STR(S_SPLIT_STRS[0])>下标从0开始的。所以这里初始变量参数1=M循环次数为0.   参数2=检测M循环次数 < M数据数量  继续循环。 参数3=每次循环 M循环次数加1
#For (M循环次数 = 0, M循环次数 < M数据数量, M循环次数 + 1)
#if
True
#Act
;每次循环输出结果。这里也可以直接拆分字符。然后用来计算等操作。
Sendmsg 7 合成结果<$Str(M循环次数)>:<$STR(S_SPLIT_STRS[<$Str(M循环次数)>])>
#~For

关键点

  • 三个命令的格式:RegExMatch 源字符 匹配表达式、RegExSplitCapture 源字符 查找表达式、RegExReplace S1 查找表达式 替换字符 替换次数(默认1次)(结果仍写回 S1)。
  • RegExSplitCapture 的结果变量:匹配数量 <$STR(M_MATCHED_CNT)>、匹配串 <$STR(S_MATCHED_STRS[n])>;剩余数量 <$STR(M_SPLIT_CNT)>、剩余串 <$STR(S_SPLIT_STRS[n])>,下标从 0 开始。
  • 文档给出的表达式示例:手机号 "1[34578]\d{9}"、NPC 说话内容里的 16 进制颜色 "\$[0-9A-Fa-f]+"、网址 "[a-zA-Z]+:\/\/"。
  • 示例部分演示了先用普通 StringReplace 把 | 换成 *、再复制 S12/S13 做分隔的完整流程,可当作“物品名|数量”这类数据串的解析模板。

相关阅读