Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 如何确定一个正则表达式是否与另一个正则表达式正交?_Regex_Fsm - Fatal编程技术网

Regex 如何确定一个正则表达式是否与另一个正则表达式正交?

Regex 如何确定一个正则表达式是否与另一个正则表达式正交?,regex,fsm,Regex,Fsm,我想我的问题最好用一个(简化的)例子来解释 正则表达式1: ^\d+_[a-z]+$ 正则表达式2: ^\d*$ 正则表达式1永远不会匹配正则表达式2匹配的字符串。 假设正则表达式1与正则表达式2正交 正如许多人问我所说的正交是什么意思,我将试图澄清: 设S1为正则表达式1匹配的(无限)字符串集。 S2是正则表达式2匹配的字符串集。 当S1和S2的交点为空时,正则表达式2与正则表达式1正交。 regex^\d_a$将不是正交的,因为字符串“2_a”在集合S1和S2中 如果两个正则表达式彼此正

我想我的问题最好用一个(简化的)例子来解释

正则表达式1:

^\d+_[a-z]+$
正则表达式2:

^\d*$
正则表达式1永远不会匹配正则表达式2匹配的字符串。 假设正则表达式1与正则表达式2正交

正如许多人问我所说的正交是什么意思,我将试图澄清:

设S1为正则表达式1匹配的(无限)字符串集。 S2是正则表达式2匹配的字符串集。 当S1和S2的交点为空时,正则表达式2与正则表达式1正交。 regex^\d_a$将不是正交的,因为字符串“2_a”在集合S1S2中

如果两个正则表达式彼此正交,如何通过编程确定

最好的情况是实现以下方法的库:

/**
 * @return True if the regex is orthogonal (i.e. "intersection is empty"), False otherwise or Null if it can't be determined
 */
public Boolean isRegexOrthogonal(Pattern regex1, Pattern regex2);

您可以使用类似的方法生成与指定正则表达式匹配的测试字符串,然后使用第二个正则表达式上的测试字符串来确定这两个正则表达式是否正交。

在某些情况下,证明一个正则表达式与另一个正则表达式正交可能很简单,例如,在相同位置的互斥字符组。对于除最简单的正则表达式之外的任何正则表达式来说,这都是一个非常重要的问题。对于严肃的表达,包括分组和反向引用,我甚至认为这可能是不可能的。

所谓“正交”你的意思是“交叉点是空集”,我认为是吗

我会为交集构造正则表达式,然后转换成正规形式的正则语法,看看它是否是空语言

再说一遍,我是一个理论家…

我相信你用正交法来表示是正确的。


这是正确的吗?

首先让我说,我不知道如何构造这样一个算法,也不知道有哪个库实现了它。然而,如果知道任意复杂的一般正则表达式不存在这样的情况,我一点也不会感到惊讶

每一个正则表达式都定义了一种正则语言,它包含了该表达式可以生成的所有字符串,或者如果您愿意的话,还定义了所有与正则表达式“匹配”的字符串。将语言视为一组字符串。在大多数情况下,集合将无限大。您的问题是,正则表达式给出的两个集合的交点是否为空

至少在一级近似下,我无法想象一种不计算集合的方法来回答这个问题,而对于无限集合,计算集合的时间会比你想象的要长。我认为可能有一种方法可以计算一个有限的集合,并确定什么时候在其他正则表达式所要求的范围之外详细描述一个模式,但这并不简单

例如,只需考虑简单表达式<代码>(ab)*< /COD>和<代码>(ABA)*B<代码>。什么算法会决定从第一个表达式生成

abab
,然后停止,而不检查
abababab
abababab
等,因为它们永远不会工作?您不能只生成字符串并检查,直到找到匹配项,因为当语言不相交时,这将永远不会完成。我无法想象在一般情况下会有什么效果,但在这方面有比我更好的人


总而言之,这是一个难题。如果我知道有多项式时间的解,我会有点惊讶,如果我知道它等价于停顿问题,我也不会感到惊讶。虽然,鉴于正则表达式不是图灵完全的,但似乎至少有可能存在一个解决方案。

我将执行以下操作:

  • 使用如下结构将每个正则表达式转换为FSA:

    struct FSANode
    {
        bool accept;
        Map<char, FSANode> links;
    }
    List<FSANode> nodes;
    FSANode start;
    
    struct
    {
    布尔接受;
    地图链接;
    }
    列出节点;
    阳极启动;
    
请注意,这并不是一件小事,但对于简单的正则表达式来说应该没有那么困难

  • 创建一个新的组合节点,如:

    class CombinedNode
    {
        CombinedNode(FSANode left, FSANode right)
        {
            this.left = left;
            this.right = right;
        }
    
        Map<char, CombinedNode> links;
        bool valid { get { return !left.accept || !right.accept; } }
    
        public FSANode left;
        public FSANode right;
    }
    
    类组合节点
    {
    组合节点(左FSANode,右FSANode)
    {
    this.left=左;
    这个。右=右;
    }
    地图链接;
    bool valid{get{return!left.accept | | |!right.accept;}}
    公营部门:左派;
    公权力;
    }
    
基于在左侧和右侧跟随相同的字符建立链接,您将得到两个FSAnode,它们构成一个新的CombinedNode

然后从CombinedNode(leftStart,rightStart)开始,找到生成集,如果有任何无效的CombinedNode,则该集不是“正交的”。

可以在有限状态机上执行各种操作,唯一的问题是将正则表达式的字符串表示形式转换为fsmtools可以使用的格式。对于简单的情况,这当然是可能的,但是如果有像look{ahead,behind}这样的高级特性,这将是很棘手的

你也可以看看,虽然我从来没用过。不过,它支持交叉

我会为交集构造正则表达式,然后转换成正规形式的正则语法,看看它是否是空语言

那就像是用大炮射杀麻雀。为什么不构建产品自动机并检查是否可以从初始状态访问接受状态?这还将直接在交叉点处为您提供一个字符串,而无需首先构造正则表达式

如果我知道有多项式时间的解,我会有点惊讶,如果我知道它等价于停顿问题,我也不会感到惊讶

我只知道一种方法,它涉及从regexp创建DFA,这是指数时间(在退化情况下)。它可以简化为停顿问题,因为一切都是,但是停顿问题不能简化为停顿问题

如果是最后一个,那么你可以用
$ ./binaries/osx/genex '^\d+_[a-z]+$' '^\d*$'
$
$ runghc Main.hs '\d' '[123abc]' 
1.00000000      "2"
1.00000000      "3"
1.00000000      "1"
/**
 * @return true if the two regexes will never both match a given string
 */
public boolean isRegexOrthogonal( String regex1, String regex2 ) {
   Automaton automaton1 = new RegExp(regex1).toAutomaton();
   Automaton automaton2 = new RegExp(regex2).toAutomaton();
   return automaton1.intersection(automaton2).isEmpty();
}