A pattern cut with a laser用激光切割的图案
JMP 的模式匹配功能可以做到几乎正则表达式可以做的所有事情和稍微多一点. 在内部,正则表达式是由模式匹配函数构建的,并且具有易于使用的界面。 你可能永远不需要稍微多一点,所以如果你有使用正则表达式的经验,它可能是一个不错的选择。 或者,您可能会发现模式匹配语言更有吸引力。 这些正则表达式可能非常不透明。
最简单的模式匹配可能如下所示:
source = "the old fox had eggs for breakfast";
ok = patMatch( source, "eggs" ); // ok will be 1 because the pattern "eggs" is found
1
把鸡蛋换成培根:
source = "the old fox had eggs for breakfast";
ok = patMatch( source, "eggs", "bacon" ); // 3rd argument is the replacement text
print(source);
"the old fox had bacon for breakfast"
并找出狐狸吃什么:
morningMeal = .;
source = "the old fox had yogurt for breakfast";
foods = "eggs" | "bacon" | "yogurt" | "honey";
ok = patMatch( source, foods >? morningMeal ); // >? is an assign-to-the-right operator for patterns
print(morningMeal );
"yogurt"
如果你以前没有见过这些模式,你可能会对看起来很奇怪的任务感到困惑食物. 那些单竖线表示“或”。 它们不是用于连接字符串的双竖线。食物是一个匹配这四个单词中的任何一个的模式值。 还有一个用于连接模式的 + 运算符(与连接字符串不同)。 让我们加强这个例子:
source = "the old fox had yogurt for breakfast, honey for dinner, and bacon for lunch, but eggs at bedtime.";
foods = "eggs" | "bacon" | "yogurt" | "honey";
morningMeal=.;
middayMeal=.;
eveningMeal=.;
ok1 = patMatch( source, ( foods >? morningMeal + " for breakfast" ) );
ok2 = patMatch( source, ( foods >? middayMeal + " for lunch" ) );
ok3 = patMatch( source, ( foods >? eveningMeal + " for dinner" ) );
show(morningMeal, middayMeal, eveningMeal);
morningMeal = "yogurt";
middayMeal = "bacon";
eveningMeal = "honey";
三个单独的匹配项来查找食物,然后是一天中的某个时间(使用 + 连接模式)。 您还可以通过简单的步骤构建更复杂的模式:
首先,一个匹配数字范围的小模式
digits = patSpan("0123456789");
然后是使用数字模式匹配数字的模式,例如-314.15E-2 . "" 选项不允许匹配任何内容,因此符号、小数、分数和指数是可选的。
number = ( "" | "-" ) // optional sign
+ ( digits + ( "." + ( ( digits ) | "" ) | "" ) ) // leading digit not optional
+ ( ( ("E"|"e") + ( "" | "-" ) + digits ) | "" ) ; // another optional sign in the optional exponent
这是不是一种模式;引号很丑(他们需要转义)所以做一个变量
quote = "\!""; // nightmare -> thing of beauty
接下来是匹配引号中的文本的模式;在里面源文件text(下),嵌入的引号表示为两个引号。 因此,这种模式更难确保引号对保持在一起。拍重复()将尽可能多地重复其论点。 patBreak()将匹配,但不包括,它的论点。帕特伦()用来代替 "" 只是为了炫耀它;它匹配请求的字符数。 因此,文字以引号开头和结尾,并且在两者之间有一系列字符直到引号。 请记住 patBreak 不包括引号......所以要么有两个引号并重复一些,要么停止重复并找到最后的引号。
literal = quote + patRepeat( patBreak(quote) + ( ( quote + quote ) | patLen(0) ) ) + quote;
这个小模式匹配不同操作系统使用的各种行尾字符
newline = "\!r\!n" | "\!r" | "\!n" | "\!N";
示例输入中的字段由逗号、文件开头、文件结尾或换行符分隔。拍点()和patRPos()如果当前位置与参数匹配,则匹配零长度字符串。 patRPos(0)是字符串的右端。拍拍位置(0)是字符串的开头。
endOfField = "," | newline | patPos(0) | patRPos(0);
这是要匹配的示例文本,使用特殊的括号转义,因此引号不需要更多转义。
sourcefile = "\[
-123.456e-78,"I said,""how are you?""",11,555-5555,"fine, thank you",3.1459,1.414
]\";
最后!一个while循环来查找模式并用逗号替换它,每次都打印找到的文本。 最后,显示不匹配的文本。
while(patMatch(sourcefile, endOfField + (number | literal ) >? found + endOfField , ","),
write(found || "\!n") // display the found text and a newline
);
write( "Non matches: ", sourceFile, "\!n");
-123.456e-78
"I said,""how are you?"""
11
"fine, thank you"
3.1459
1.414
Non matches: ,555-5555,
>?运算符是模式中的条件赋值。 只有在模式成功并且 patMatch() 返回 1 后才会进行分配。 还有一个 >> 运算符,用于在文本匹配后立即进行分配(如果模式匹配器必须备份并重试,则可能多次。)
JSL 中的模式匹配可以做其他有趣的事情,比如在单个语句中循环一个长字符串,这可能会加快原本缓慢的过程。 这正则表达式()函数允许您使用正则表达式作为模式匹配的一部分。 脚本索引(来自帮助菜单)有一个模式匹配函数和描述的列表。
更新 30jan2017:修复新社区的格式。