用正则表达式并不擅长解决数学问题。对一个正则表达式系统,字符从0到9,和其他的一样,并没有什么特殊的地方。

  在这里我需要提到两个例外Perl和PCRE,这两个例外允许动态代码在匹配过程中的任何一点上运行,这为我们提供了大量额外的契机。Perl是通过代码嵌入正则表达式,PCRE用标注系统去表达外部函数。但正则表达式偏好这些例外,甚至利用他们去拓展自己的能力,让方程式告诉你更多,呈现的更完整。一般的,有关数学的问题像匹配数值范围(matching numeric ranges)(在匹配一些需画大量时间的长文本的任务上很有用)在运行中是一个痛,如果他们有可能的话。

  但是在最基本的正则表达式的系统中,这种力量和表现可以引导出一些漂亮的技巧。就像匹配非素长度字符串一样!这时基础的正则表达式就有些出名了。就连一个黑客也会惊讶你是用的是正则表达式来解决的一个简单的线性方程组。我在摆弄 RegexBuddy's 的调试器时无意中蹦出了这个想法。严格的POSIX ERE的实现和其他深邃的味道,不允许反向引用,因此执行本生是简单的,工作也相当普遍。这里有一个样板:

  ^(.*)\1{A?1}(.*)\2{B?1}$

  现在让我们来解关于x和y的方程,像17X+12y=51 ,A和B是常量占位符对应这个例子中的17和12.所以正则表达式成为^(.*)\1{16}(.*)\2{11}$我们从A,B值中减去1因为我们重复反向引用,而子模式之前已经匹配过一次。如果你运行正则表达式去对付51字符串,当长度为$1时(反向引用1)将会是3(这就告诉我们x=3),当长度为$2时(反向引用2)将会是0(意味着y=0)事实上17*3+12*0=51.如果方程没有解,那么正则表达式将无法匹配字符串。如果方程有多种可能的解,那么返回的是x的最大值,因为这个值最早被处理。

  快来尝试吧!你可以用正则表达式来解各种各样的你喜欢的形式类似的方程。例如11x+2y+5z=115可以用^(.*)\1{10}(.*)\2{1}(.*)\3{4}$和115字符的源串来解决(结果是11*10+2*0+5*1=115)。运行^(.*)\1{12}$去对付247字符的字符串,那么你将会因为反向引用一次得到一个19字符的值,像13*19=247.请记住,随着整数和字符串的长度的增加,变量的数目增加,通过正则表达式软件的回溯的数量也会增加。对于一些图像的门栏这种方法是很慢的甚至无用的。但我不在乎,他依然很酷!

09-03 12:00