正则太麻烦了,我又太笨,学不会,就自己随便设计一个。当然也只是随便设计而已。
'' 括起来的字符串表示是独立的单词,如输入 'hello' 则不会和 helloworld 匹配
"" 括起来的字符串表示可与其他,如输入 "hello" 则会与 helloworld 匹配
在一个匹配节中,紧挨在前面的数字是重复次数,空表示一次,多次可用空格分开, - 表示连续,如 (digit) 表示匹配一个数字,2(number) 表示匹配两个数字(如 10, 99,但不匹配 1、100),*(digit) 匹配一以上位数字,^(digital) 匹配零以上位数字。
(digit 接受的数字):匹配一个数字([0,9]),不独立。也可以在这里使用连续的列表。如 (digit 100-200) 表示匹配在 [100,200] 中的一切整数,此时无视“一个数字”限制。
(standalone):强制独立,即使写成 (standalone "str") 也视作 'str';写作 (standalone (digit)) 则匹配一个独立的数字,如匹配 1 不匹配 12,写作 2(standalone (digit)) 或 *(standalone (digit)) 则匹配 “1 2” “2 4” 等有间隔的数字。
(join 一系列东西 中间插入的东西):匹配如同 join 返回的结果一样的文本,如 (join *(digit) ".") 匹配 1.2.3.4.100 和 100.300.600.0.1 等。
(or 选择一 选择二 选择三):使用多种方式匹配,若相同一段文本在三种选择中都匹配,则返回匹配长度最长的一种。
(have 名字 匹配格式):自定义匹配方法。如 (have number (or (digit 0) "") "." *(digit)),以后就可以使用 (number) 来匹配
(match 起始 结束):匹配有开始和结束的一段文本。匹配最长的文本。如 "{{ a } b} {c}" 则匹配得到 "{{ a } b}" 和 "{c}",{ a } 并不放出。
(match 起始结束):如双引号,本身就可以结束自己。
(line 位置 匹配节):位置可以是 start,end,middle。
一个 () 代表一个匹配节,是一个逻辑单位,[] 作用与 () 相同,只是为了避免嵌套过多难于阅读。
上面这些看着有点像是文本处理的 DSL 了,举些例子:
# IPv4 地址 (join 4(digital 0-255) ".") # 浮点数(要求有小数点) (or [^(digital) "." ^(digital)] [*(digital) "." ^(digital)] [^(digital) "." *(digital)]) # 电话号码(3或4位区号+横线(连接在一起或没有连接在一起)+7或8位电话) 3,4(digital) (or "-" '-') 7,8(digital) # 随便什么。。 (match 'for' 'next') # 匹配 ⑨ 个独立的数字 (have float (or [^(digital) "." ^(digital)] [*(digital) "." ^(digital)] [^(digital) "." *(digital)])) (have integer ^(digital)) (have number (or (integer) (float))) 9(standalone (number))