今天发现一个在线调试正则的网站:http://www.debuggex.com/。写了一个正则式,有NFA图示,有匹配测试框和匹配结果说明,效果非常不错,见下图:
开始以为NFA就是个图片,光标放上去想右键保存到本地,结果发现图中的字符竟然可以选择,于是用Firefox的开发工具看看是什么,下面是真面目:
这就是传说中的SVG,看一下代码:
<svg width="434" height="115"> <g style="display: inline;" transform="translate(41, 64)"> <g> <g> <g transform="translate(20, -1)"> <g> <rect class="nfa-literal" x="0" y="-9" rx="2" ry="2" width="14" height="20"></rect> <text class="nfa-literal-text" transform="translate(4, 4)"> <tspan class="nfa-escaped" style="letter-spacing: 0px;" dx="0">•</tspan> </text> <path class="nfa-path" d="M0,1H-4"></path> <path class="nfa-path" d="M14,1H18"></path> <rect class="nfa-marker sa-orange" x="4" y="-9" width="2" height="20"></rect> </g> <path class="nfa-path" d="M18,1Q26,1,26,9V11Q26,19,18,19H-4Q-12,19,-12,11V9Q-12,1,-4,1"></path> <path class="nfa-path" d="M34,1Q26,1,26,-7V-9Q26,-17,18,-17H-4Q-12,-17,-12,-9V-7Q-12,1,-20,1"></path> <path class="nfa-path" d="M-4,1H-20"></path> <path class="nfa-path" d="M18,1H34"></path> </g> <g transform="translate(78, -38)"> <rect class="nfa-match" x="-20" y="-8" width="110" height="92" rx="5" ry="5"></rect> <g> <g transform="translate(4, 9)"> <rect class="nfa-literal" x="0" y="-9" rx="2" ry="2" width="62" height="20"></rect> <text class="nfa-literal-text" transform="translate(4, 4)"> <tspan style="letter-spacing: 0px;" dx="0">w</tspan> <tspan style="letter-spacing: 0px;" dx="2">i</tspan> <tspan style="letter-spacing: 0px;" dx="2">n</tspan> <tspan style="letter-spacing: 0px;" dx="2">d</tspan> <tspan style="letter-spacing: 0px;" dx="2">o</tspan> <tspan style="letter-spacing: 0px;" dx="2">w</tspan> <tspan style="letter-spacing: 0px;" dx="2">s</tspan> </text> <path class="nfa-path" d="M0,1H-4"></path> <path class="nfa-path" d="M62,1H66"></path> <rect class="nfa-marker sa-orange" x="4" y="-9" width="2" height="20"></rect> </g> <g transform="translate(20, 37)"> <rect class="nfa-literal" x="0" y="-9" rx="2" ry="2" width="30" height="20"></rect> <text class="nfa-literal-text" transform="translate(4, 4)"> <tspan style="letter-spacing: 0px;" dx="0">w</tspan> <tspan style="letter-spacing: 0px;" dx="2">i</tspan> <tspan style="letter-spacing: 0px;" dx="2">n</tspan> </text> <path class="nfa-path" d="M0,1H-4"></path> <path class="nfa-path" d="M30,1H34"></path> <rect class="nfa-marker sa-orange" x="4" y="-9" width="2" height="20"></rect> </g> <g transform="translate(16, 65)"> <rect class="nfa-literal" x="0" y="-9" rx="2" ry="2" width="38" height="20"></rect> <text class="nfa-literal-text" transform="translate(4, 4)"> <tspan style="letter-spacing: 0px;" dx="0">w</tspan> <tspan style="letter-spacing: 0px;" dx="2">i</tspan> <tspan style="letter-spacing: 0px;" dx="2">n</tspan> <tspan style="letter-spacing: 0px;" dx="2">8</tspan> </text> <path class="nfa-path" d="M0,1H-4"></path> <path class="nfa-path" d="M38,1H42"></path> <rect class="nfa-marker sa-orange" x="4" y="-9" width="2" height="20"></rect> </g> <path class="nfa-path" d="M-16,38Q-8,38,-8,30V18Q-8,10,0,10H0"></path> <path class="nfa-path" d="M86,38Q78,38,78,30V18Q78,10,70,10H70"></path> <path class="nfa-path" d="M-16,38C0,38,0,38,16,38"></path> <path class="nfa-path" d="M86,38C70,38,70,38,54,38"></path> <path class="nfa-path" d="M-16,38Q-8,38,-8,46V58Q-8,66,0,66H12"></path> <path class="nfa-path" d="M86,38Q78,38,78,46V58Q78,66,70,66H58"></path> </g> <path class="nfa-path" d="M-16,38H-24"></path> <path class="nfa-path" d="M86,38H94"></path> <text class="nfa-label" x="35" y="-10">Group 1</text> </g> <g transform="translate(192, -1)"> <g> <rect class="nfa-literal" x="0" y="-9" rx="2" ry="2" width="14" height="20"></rect> <text class="nfa-literal-text" transform="translate(4, 4)"> <tspan class="nfa-escaped" style="letter-spacing: 0px;" dx="0">•</tspan> </text> <path class="nfa-path" d="M0,1H-4"></path> <path class="nfa-path" d="M14,1H18"></path> </g> <path class="nfa-path" d="M18,1Q26,1,26,9V11Q26,19,18,19H-4Q-12,19,-12,11V9Q-12,1,-4,1"></path> <path class="nfa-path" d="M34,1Q26,1,26,-7V-9Q26,-17,18,-17H-4Q-12,-17,-12,-9V-7Q-12,1,-20,1"></path> <path class="nfa-path" d="M-4,1H-20"></path> <path class="nfa-path" d="M18,1H34"></path> </g> <g transform="translate(230, -1)"> <rect class="nfa-literal" x="0" y="-9" rx="2" ry="2" width="14" height="20"></rect> <text class="nfa-literal-text" transform="translate(4, 4)"> <tspan style="letter-spacing: 0px;" dx="0">.</tspan> </text> <path class="nfa-path" d="M0,1H-4"></path> <path class="nfa-path" d="M14,1H18"></path> </g> <g transform="translate(272, -24)"> <rect class="nfa-match" x="-20" y="-8" width="86" height="64" rx="5" ry="5"></rect> <g> <g transform="translate(4, 9)"> <rect class="nfa-literal" x="0" y="-9" rx="2" ry="2" width="38" height="20"></rect> <text class="nfa-literal-text" transform="translate(4, 4)"> <tspan style="letter-spacing: 0px;" dx="0">e</tspan> <tspan style="letter-spacing: 0px;" dx="2">p</tspan> <tspan style="letter-spacing: 0px;" dx="2">u</tspan> <tspan style="letter-spacing: 0px;" dx="2">b</tspan> </text> <path class="nfa-path" d="M0,1H-4"></path> <path class="nfa-path" d="M38,1H42"></path> </g> <g transform="translate(8, 37)"> <rect class="nfa-literal" x="0" y="-9" rx="2" ry="2" width="30" height="20"></rect> <text class="nfa-literal-text" transform="translate(4, 4)"> <tspan style="letter-spacing: 0px;" dx="0">p</tspan> <tspan style="letter-spacing: 0px;" dx="2">d</tspan> <tspan style="letter-spacing: 0px;" dx="2">f</tspan> </text> <path class="nfa-path" d="M0,1H-4"></path> <path class="nfa-path" d="M30,1H34"></path> </g> <path class="nfa-path" d="M-16,24C-8,24,-8,10,0,10"></path> <path class="nfa-path" d="M62,24C54,24,54,10,46,10"></path> <path class="nfa-path" d="M-16,24C-6,24,-6,38,4,38"></path> <path class="nfa-path" d="M62,24C52,24,52,38,42,38"></path> </g> <path class="nfa-path" d="M-16,24H-24"></path> <path class="nfa-path" d="M62,24H70"></path> <text class="nfa-label" x="23" y="-10">Group 2</text> </g> <g transform="translate(346, -1)"> <rect class="nfa-literal" x="0" y="-9" rx="2" ry="2" width="14" height="20"></rect> <text class="nfa-literal-text" transform="translate(4, 4)"> <tspan class="nfa-escaped" style="letter-spacing: 0px;" dx="0">$</tspan> </text> <path class="nfa-path" d="M0,1H-4"></path> <path class="nfa-path" d="M14,1H18"></path> </g> </g> <path class="nfa-path" d="M0,0H-8"></path> <path class="nfa-path" d="M364,0H372"></path> <path class="nfa-path" d="M-24,0L-36,0M-24,0L-28.8,-3.2M-24,0L-28.8,3.2"></path> <circle class="nfa-start" cx="-16" cy="0" r="8"></circle> <circle class="nfa-end" cx="380" cy="0" r="8"></circle> </g> </g> <g></g> </svg>