Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.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_Rust - Fatal编程技术网

Regex 如何检查字符串是否是正则表达式的有效前缀?

Regex 如何检查字符串是否是正则表达式的有效前缀?,regex,rust,Regex,Rust,所以我正在使用Rust为我的编程语言构建一个解析器,我需要它来很好地。。。作语法分析我正在实现一个Stream结构,它负责对所拥有的Vec执行一些基本操作。其中一项职能如下: fn在正则表达式匹配(&self,regex:regex,mut acc:String)->(self,String)时使用正则表达式 它是一个递归函数,接受一个正则表达式和一个累加器,在流中的下一个字符使其不再与正则表达式匹配之前,它应该填充累加器。我会使用这个函数来匹配简单的标记,比如整数、字符串等 我尝试以以下方式

所以我正在使用Rust为我的编程语言构建一个解析器,我需要它来很好地。。。作语法分析我正在实现一个Stream结构,它负责对所拥有的
Vec
执行一些基本操作。其中一项职能如下:

fn在正则表达式匹配(&self,regex:regex,mut acc:String)->(self,String)时使用正则表达式
它是一个递归函数,接受一个正则表达式和一个累加器,在流中的下一个字符使其不再与正则表达式匹配之前,它应该填充累加器。我会使用这个函数来匹配简单的标记,比如整数、字符串等

我尝试以以下方式实现它(这不是确切的版本,但它解释了问题):

acc.push(self.peek())
如果!regex.is_match(){
根据pop();
返回self.clone(),acc;
}
返回self.consumer_而_regex_匹配(regex,acc);
此代码的问题在于它正在测试
acc
是否与整个正则表达式匹配。想象一下,如果我们想使用一个字符串
-42
和一个类似于
^-[0-9]+$
的正则表达式。算法将读取第一个字符
-
,匹配将失败,累加器将为空

是否有方法检查字符串(例如,
acc
)是否是潜在正则表达式匹配的前缀? Like
-
本身不是匹配项,但是
-42
是匹配项,
-
是有效前缀。 如果它像一个图书馆的方式,它不需要我生产自己的正则表达式引擎,那就太好了

更新:我没有使用所描述的函数进行解析。我用它来词法分析。我知道regex不足以解析复杂的语言


我要问的是,我是否可以使用一些正则表达式库来逐渐匹配令牌,而不是必须提供整个字符串来匹配。我正在寻找一种方法来检查底层DFA是否在字符串行进结束时处于错误状态,而不必编写自己的正则表达式解析器和DFA实现。如果这是可能的,我会将
-
传递给整数正则表达式,检查行军后它没有进入错误状态,如果是,它是一个有效的前缀。

正则表达式基本上是一种简洁的格式,用于处理字符/字符串输入的状态机,无论,根据您需要接受/拒绝的语言的复杂性

您的方法是构建字符串,直到它与复杂的正则表达式匹配为止,但是为了提高效率,正则表达式通常会重新编译到状态机中。这些状态机的工作方式是将复杂的正则表达式分解为各个状态,然后针对这些状态逐个令牌(或逐个字符)解析和转换状态。最终正则表达式可能有许多不同的状态。以下是一个(有点不恰当的)FSM示例,用于
[+-][1-9][0-9]*
,其中
s2
作为接受状态:

是否有方法检查字符串(例如acc)是否是潜在正则表达式匹配的前缀?Like-本身不是匹配项,但是-42是匹配项,并且-是有效前缀。如果它像一个图书馆的方式,它不需要我生产自己的正则表达式引擎,那就太好了

您可以使用纯正则表达式来解决更简单的解析问题,但如果您正在构建一种编程语言,您最终将寻找一个解析库来处理任意嵌套深度的解析(这需要一个比正则表达式更强大的系统)。在Rust中,最流行的板条箱之一是。Nom是一个风格库,这意味着它依赖于以不同的方式将较小的解析器与称为“组合器”的“运算符”组合在一起。正则表达式通常是一种较弱的解析器形式,因为它们的运算符/组合器数量有限,属性有限


我还将注意到,验证用编程语言编写的正确程序的全部工作都不会满足于这两种方法,这就是为什么我们要费心超越词法分析/解析过程的原因。所有传统和正确的编程语言都介于上下文敏感语法和图灵完整语言之间,这意味着单独解析无法满足您的需求,因为还有其他上下文和语义信息需要通过类型检查、引用检查、,等等。

从表面上看问题。板条箱(由一位作者维护)提供了一些对构建和解析正则表达式的底层细节的访问。特别是,您可以自己访问和驱动内部DFA(确定性有限自动机)

use regex_automata::{Regex, DFA}; // 0.1.9

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
enum PotentialMatch {
    Match,
    CouldMatch,
    DoesntMatch,
}

fn potentially_matches(pattern: &Regex, input: &str) -> PotentialMatch {
    let input = input.as_bytes();
    let dfa = pattern.forward();
    let mut state = dfa.start_state();
    for byte in input {
        state = dfa.next_state(state, *byte);
        if dfa.is_dead_state(state) {
            return PotentialMatch::DoesntMatch;
        }
    }
    
    if dfa.is_match_state(state) {
        PotentialMatch::Match
    }
    else {
        PotentialMatch::CouldMatch
    }
}

fn main() {
    let pattern = Regex::new("-[0-9]+").unwrap();
    
    assert_eq!(potentially_matches(&pattern, ""), PotentialMatch::CouldMatch);
    assert_eq!(potentially_matches(&pattern, "-"), PotentialMatch::CouldMatch);
    assert_eq!(potentially_matches(&pattern, "-1"), PotentialMatch::Match);
    assert_eq!(potentially_matches(&pattern, "-12"), PotentialMatch::Match);
    assert_eq!(potentially_matches(&pattern, "-12a"), PotentialMatch::DoesntMatch);
}

您可能会将此状态跟踪集成到实现中,以便通过反复调用
潜在的匹配()来提高性能。

我认为正则表达式不是正确的方法。在许多lexer中,您会发现类似的状态机,我认为lexer正是您所需要的:因为您想要交互的东西,所以需要将lexer和解析器分开。Rust中有很多lexer lib,因此您不必从零开始;可能是一个板条箱。它有内置的解析器,形成一些典型的标记,如整数,并支持流模式。@SvenMarnach看起来nom可能会帮助我实现这一点,但我有点担心它可能无法很好地扩展,因为它实际上迫使您使用这些小函数指定正则表达式。对于我的用例,我更希望有一个DFA实现,它可以一个接一个地消耗字符并返回Self进行检查。如果这样的DFA在使用字符后处于错误状态,那么匹配肯定是失败的,否则它可能是有效的前缀。(阅读我发布的更新,我在那里解释得更好)Regex不是灵活报告错误的合适工具。在某种意义上,您的DFA思想已经嵌入到解析器组合器的工作方式中。插入