我想知道是否有办法查看正则表达式的一部分是否具有确定性。例如,正则表达式$current_month = 3;
$other_month = 10;
if($current_month>=$other_month)
{
echo $current_month-$other_month+1;
}
else
{
echo (12-$other_month)+$current_month+1;
}
是确定性的a.k.a只有一个匹配它的字符串:0{3}
。因此,例如,如果我们将正则表达式"000"
与字符串\d0{3}
一起使用,是否有办法从中获取字符串"1"
?这似乎在技术上是可行的,因为一旦你有了第一个数字,你知道其余的数字都是0,而且只能有3个数字。我不知道我是否遗漏了某些东西。
答案 0 :(得分:1)
正则表达式具有确定性的充分条件是它不包含:
|
运营商。+
)以外的任何量词(*
,?
,{n,m}
,{n}
)。\w
,[a-z]
)由于零宽度断言,这些条件不是必需。例如,表达式(?!x)(x|y)
仅匹配y
。因此,这种简单的方法不会涵盖所有情况,但它可能足以满足您的应用。
至少对于没有反向引用的 true 正则表达式的情况,应该可以确定它们是否是单数。只需使用标准结构将表达式转换为非确定性有限自动机,然后是确定性有限自动机,然后将其最小化。当且仅当存在一个接受状态时,最小DFA是单数的,接受状态没有来自它的边缘,并且每个非接受状态都有一个边缘来自它。
要处理超前断言,您可能需要将表达式转换为交替有限自动机,然后使用类似于Thompson构造的方法来获取NFA,然后从那里继续。请注意,这里最糟糕的情况可能会出现双倍的指数性爆发。你可以把\b
和^
和类似的东西翻译成一个字符的lookbehind断言,然后做一些繁琐的东西让它们起作用。