[AS3]使用正则表达式判断加数可以交换的算式
目录
[问题]
在制作课件时经常需要判断加法算式,由于加法算式中加数满足交换律,所以加数的顺序并不是固定的,因此,答案也不是唯一的,比如正确的答案是a+b+c,如果用户输入的是a+c+b也应该判断为正确的。
[思路]
使用AS2时可以用数组或者字符串判断,这里用AS3里的正则表达式判断。正则表达式就是描述规则的,它用来检验字符串是否匹配给定的规则。因此描述清楚规则是首要的任务,这里的最明显的规则就是加数可以交换位置,其次的规则是加数只能是允许的加数范围内的数字,比如如果答案是a+b+c,那么输入了a+b+d肯定是错的。规则这两条规则,显然可以用正则表达式里的元字符|指定加数的范围,比如对于上面的例子可以写成a|b|c,这样就指定了必须是a,b,c里面的数字。为了匹配整个算式,我们把正则表达式写成(a|b|c)\+(a|b|c)\+(a|b|c),这个正则表达式可以匹配a+b+c,也匹配a+c+b,是否就是我们需要的呢?并不是这样,因为它还匹配a+a+b+c,所以改成^(a|b|c)\+(a|b|c)\+(a|b|c)$。
但是它仍然匹配a+a+a,因此我们限定加数必须不能重复,这需要构建新的正则表达式判断.(^|\+)(a|b|c)(\+|\+.+\+)\2(\+|$)这个正则表达式就是用来判断重复的加数的。分析下它的含义:
1、第一个小括号里^|\+它指的是匹配行的开头或者是+号
2、第2个括号里匹配a,b,c3个加数
3、第3个括号\+|\+.+\+它匹配一个加号或者两个加号中间跟任意内容。
4、再后面的\2是逆向引用,它指的是第2个括号匹配上的内容
5、最后一个括号里\+|$匹配的是加号或者结尾
为什么写这么麻烦呢,因为我们要判断的是是否有数字重复,而不是字符重复,如果只简单的用(a|b|c).+\1来匹配时,那么会判定a+ac为重复的,所以我们要把加数分割开来。
[实现]
核心代码如下:
- // 15 + 19 + 150 + 401
- var calcRegExp:RegExp = /^(15|19|150|401)\+(15|19|150|401)\+(15|19|150|401)\+(15|19|150|401)$/;
- var notDupReg:RegExp = /(^|\+)(15|19|150|401)(\+|\+.+\+)\2(\+|$)/g;
- function checkAnswer (str:String):Boolean
- {
- if (str == '')
- {
- return false;
- }
- return calcRegExp.test(str) && ! notDupReg.test(str);
- }
- function initStage ()
- {
- calc_txt.text = "";
- result_txt.text = "";
- result_txt.selectable = false;
- calc_txt.restrict = '0-9+';
- submit_btn.addEventListener (MouseEvent.CLICK,clickHandler);
- }
- function clickHandler (evt:MouseEvent)
- {
- if (checkAnswer(calc_txt.text))
- {
- result_txt.textColor = 0x0000FF;
- result_txt.text = "检查通过";
- }
- else
- {
- result_txt.textColor = 0xFF0000;
- result_txt.text = "检查未通过";
- }
- }
- stop ();
- initStage ();
SWF如下(需要FlashPlayer9,0,45,0及以上版本)
calc_regexp.swf
[小结]
从实现过程来看,可能觉得还不如其他方法,比如直接用字符串或数组判断简单,各取所好吧。当然了,这个程序仍然,存在问题的,就是不能判断带重复数字的算式,因为我暂时没有找到办法,望高手指点。^_^

Leave a Reply