dtp 发表于 2024-4-2 08:13:57

斜杠 / 不是元字符吧。不用加 \

maldini 发表于 2024-4-2 11:57:19

关心是什么错误

protectqiqi 发表于 2024-4-2 15:54:21

本帖最后由 protectqiqi 于 2024-4-3 09:53 PM 编辑

Perl正则表达式之二 字符类和多字符匹配
这一节好难讲好难讲,但是一定要耐心看完,因为这节的内容如果不学会的话,是没法使用后面更高的功能的。我会尽量结合实际的例子把复杂的理论讲得简单一些。
先来看一个例子:在做纪晓芙或者韩世忠任务的时候会出现好几个npc,你需要对每个npc下一次kill命令,否则就只会打晕他们而不杀死。而每次npc的名字又都是不一样的,这样怎么匹配触发呢?这就要用到字符类和多字符匹配。
输入id here的话,我们能看到一个地方的所有人物的id。比如:
要保护七七哦                     = protectqiqi护院武师                         = hu yuan吴三桂                         = wu sangui, wu, sangui夏国相                         = xia guoxiang, xia, guoxiang巴朗星                         = ba langxing, langxing, ba
玩家的id是一串连续的英文字母,而npc的姓和名中间有空格,而且可能会有个多个不同的id,每个id之间有逗号“,”隔开。利用这些规律,我们就可以做匹配啦。
Perl里有一些默认的字符类,如果你要匹配的字符在这个字符类里面,就会被匹配上。
字符类就能用来匹配所有的小写英文字母。如果你在匹配语句里输入 ,那么任意三个连续的小写英文字母都会被匹配上,不管是什么小写字母,可以是abc,xyz,yes,not,等等等等。abcdefg也能被匹配上,因为它的前三个字符也是连续的三个小写字母。但是i77就会匹配不上,因为77不是小写字母。Yes也会匹配不上,因为Y是大写字母。a b c会匹配不上,因为三个字母中间有空格。Hi, my name is 77.会被匹配上,因为这中间的name里面出现了三个连续的小写字母。
字符类\s则能用来表示空格。如果你在匹配语句里输入\s\s,那么任意两个连续的空格都会被匹配上。10个连续的空格也会被匹配上,因为里面包含了两个连续的空格。
在字符类前面加个^(键盘上打shift+6)就能匹配不包含这个字符类的字符。比如:[^a-z]可以匹配不是小写字母的字符[^0-9] 可以匹配不是数字的字符[^a-zA-Z] 可以匹配不是英文字母(包括大小写)的字符其他的字符类还有很多,我列在这个帖子的最下面了。


好了,那么[^a-zA-Z0-9_ ]可以用来匹配什么呢?这里面把字母、数字、下划线和空格都剔除了,那剩下来的不就是我们的中文了嘛。我一般就用这个字符类来匹配中文,虽然有些特殊字符和标点(比如【】,。)也会被匹配到。那么[^a-zA-Z0-9_ ][^a-zA-Z0-9_ ][^a-zA-Z0-9_][^a-zA-Z0-9_ ]就能匹配上“护院镖师”和“要保护七七哦”。[^a-zA-Z0-9_ ][^a-zA-Z0-9_ ][^a-zA-Z0-9_ ]既能匹配上“护院镖师”和“要保护七七哦”,又能匹配上“吴三桂”,“夏国相”或“巴朗星”。


到了这里,你会发现匹配的时候居然还要计算有多少个字符,根本不好用嘛。所以,多字符匹配就登场了。在字符类的后面加上 ? * + {n,m} 等标记,就能匹配多个字符。
[字符类]?          能匹配只出现一次的字符。[字符类]*          能匹配出现0到无数次的字符。[字符类]+          能匹配出现1次到无数次的字符。[字符类]{n,m}   能匹配出现n次到m次的字符。[字符类]{n,}      能匹配出现n次到无数次的字符。[字符类]{,n}      能匹配出现0次到n次的字符。

好难理解哦,所以还是上实例吧。[^a-zA-Z0-9_ ]+能匹配1到任意长度的中文,所以“吴三桂”,“夏国相”,“巴朗星”,“护院武师”,“要保护七七哦”都会被匹配上。[^a-zA-Z0-9_ ]{4,}能匹配长度4以上的中文,只有“护院武师”和“要保护七七哦”会被匹配上。{,2}匹配两个以下连续的英文字母,所以只有hu,wu,ba。\s+会匹配上中文名字和“=”之间所有的空格。


要保护七七哦                = protectqiqi护院武师                     = hu yuan吴三桂                        = wu sangui, wu, sangui夏国相                        = xia guoxiang, xia, guoxiang巴朗星                        = ba langxing, langxing, ba


好了,终极挑战来了。一个房间里那么多id,我只想匹配npc的id,不想匹配玩家的,不然我就会kill玩家,怎么办呢?看规律!玩家和npc最大的区别就是id中间没有空格。所以就用:[^a-zA-Z0-9_ ]+\s+=\s+\s+.*

我们把这串拆开来看:[^a-zA-Z0-9_ ]+匹配前面的中文名字。\s+匹配在=之前的那串空格。=就是匹配=。\s匹配=后面的那一个空格,因为是固定的只有一个空格,所以不需要用\s+。+匹配=后面,空格前面的那一串字母。一直到这里,玩家id都是会被匹配上的。\s匹配姓名之间的那个空格。最关键的区别就在这里了,玩家的id之间没有空格,只有npc有,所以这个\s就把玩家的id剔除出去了。+这是第二个+,匹配npc的名字里的第二段英文,这里匹配到的内容就是以后我们要kill的。.*这里的.(一个小点)可以匹配任意字符。最后的这个字符类是拿来处理剩余的内容。像huyuan这样的npc在第二个+之后就没有其他字符了。而别的npc后面还有, wu, sangui之类的字符。所以这里不用.+而用.*。


到了这里,你还不知道怎么对匹配到的id进行kill,这要等学会了提取变量后才能做到,等下次再讲。
看到这里你可能已经晕了,这一节确实很难很难,我用了好几天才完全搞明白的。如果你用一两天就研究明白了,就说明你的领悟能力和我的表达能力都很强!如果搞不明白就多花一点时间,这一节不搞清楚的话,后面是进行不下去的。


最后,我把其他的一些字符类都列在下面,以后用到的时候可以来查:
数字小写字母数字和大小写字母 \d 等同于 \D 等同于 [^0-9] 即除了数字外的所有字符\s 其实是 [\\t\r\n\f] 除了空格还能匹配tab和其他一些我不懂的字符。上面我说它只表示空格是为了不吓到你们。\S 等同于[^\s]\w 等同于 大小写字母,加上数字,再加上_(下划线)\W 等同于[^\w] 注意:拿它来匹配中文并不好,因为它会匹配到空格。. (一个小点)可以匹配任意字符。

jinger 发表于 2024-4-2 15:56:31

好!好!好!

jarlyyn 发表于 2024-4-2 16:31:23

protectqiqi 发表于 2024-4-2 03:54 PM
Perl正则表达式之二 字符类和多字符匹配
这一节好难讲好难讲,但是一定要耐心看完,因为这节的内容如果不 ...

    let chinesere = /[\u4e00-\u9fa5]/g

正则匹配中文,不全,但够用。

nny 发表于 2024-4-2 16:45:45

trigger 的名字不只是帮助记忆,还可以用disableTrigger("TriggerName") 和enableTrigger("TriggerName")进行开关,避免误触发。很有用的功能。

nny 发表于 2024-4-2 16:47:39

为避免开关时出错,名字的唯一性是必要的。

protectqiqi 发表于 2024-4-2 16:55:32

dtp 发表于 2024-4-2 08:13 AM
斜杠 / 不是元字符吧。不用加 \

对哦,反斜杠是元字符,但正斜杠不是。改正了。

dtp 发表于 2024-4-2 20:16:46

「上面我说它只表示空格是为了不吓到你们」

你学会区分「空格(space character)」和「空白(whitespace)」,就不至于有这个顾虑了。

protectqiqi 发表于 2024-4-3 22:30:43

本帖最后由 protectqiqi 于 2024-4-3 10:51 PM 编辑

Perl正则表达式之三 提取变量

论坛会过滤掉一些特殊字符,导致看到的都是错误的正则表达式,只能把这一节的内容转成PDF格式放在附件里了。
页: 1 [2] 3 4
查看完整版本: 七七的Mudlet入门 (摆烂式不定期更新)