解释器和编译器是否比较(并最终匹配)两个字符串,以逐个字符和从左到右的方式进行潜在匹配?或者是否在比较函数中为每个字符串分配了基础二进制值(例如,位模式)?或者它取决于以某种方式编码的字符串(ASCII或UTF-32),还是解释器,编译器,数据库引擎或编程语言?
重新设计数据存储(数据文件或数据库)是一项相当大的工作。 stackoverflow上类似问题的答案并没有明确地描述编码问题(是否正在评估位模式或实际的字母字符)。这个问题的答案对于优化工作可能很重要。
我不想知道如何实现正则表达式(例如,写我自己的)。出于教育目的,我想知道以最佳方式使用现有正则表达式的好处(例如,当设计数据作为子串的组合存储时,我应该注意从左到右的评估)。类似的StackOverflow问题answer(这是一个具有不受信任的证书来查看它的链接)侧重于有限自动机(如何比较字符串的理论)。这个答案强调它如何工作以及比较字符串的计算复杂性。它确实意味着存在从左到右的角色评估。我不认为它无论如何都是决定性的。这篇文章主要针对Perl和语言无关的Thomson非确定性有限自动机算法。我想知道这三种技术组合:1)使用ASCII数据文件的Java本机函数,2)MySQL(表数据和SELECT语句),以及3)使用Python本机函数和UTF-32数据文件。
我的问题和方法与旧文章的不同之处在于我没有尝试开发用于执行正则表达式的解析器。我正在尝试构建数据以供将来开发。我想知道如何以最佳方式利用现有的正则表达式工具。我相信stackoverflow是正确的论坛,因为它是正则表达式的核心,并且这个问题以其原始且不那么冗长的形式被投票。
我想知道在CPU级别,字符串模式是字符串中字符的表示吗?是否存在与参与比较的字符串的每个字符相对应的位模式的短寿命索引,其中一个字符串被锚定?我认为技术(例如数据库,编程语言和/或数据编码)会有所不同。
答案 0 :(得分:6)
有两大类正则表达式引擎,名为 NFA 和 DFA (我使用了Jeffrey Friedl的书中的术语):< / p>
NFA实施将大致以下列方式运作:
然后将该模式用作如何在输入字符串中前进的配方。例如,如果模式显示a
,并且当前输入偏移指向a
字符,那么该字符将消耗指针将前进到下一个位置。如果角色不匹配,则会有回溯(输入指针将转到先前的有效位置,并且模式指针将在输入位置设置为不同的可能替代)。
重点在于识别是由模式驱动的。
(上面的解释非常粗略,因为它不包括优化等 - 现代模式无法用正式的自动机实现)
DFA实现的另一种方式是:
仍有一个输入指针,但有多个模式指针。输入模式将逐个字符前进,模式指针将跟踪给定输入模式中的有效状态。
识别由输入驱动。
这两种方法都具有非常不同的属性:
某些正则表达式引擎(如PCRE)可以实现这两种识别方法。我建议您阅读有关两种匹配算法的PCRE docs,它们解释了更多技术术语的差异。
对于实际实现,它高度依赖于正则表达式引擎本身。 PCRE有几个:
因此,您实际上可以看到有几种可能的NFA方法。其他引擎具有允许不同功能集的不同实现。例如,.NET的正则表达式可以从左到右或从右到左匹配,因此可以轻松提供可变长度的后视,而PCRE的后视是通过临时移位输入指针来实现的。由lookbehind的预期输入长度向左,并从该偏移执行从左到右的匹配。
答案 1 :(得分:2)
正则表达式不指定实现细节。由语言决定将它们编译为机器代码的最佳方法。例如,这个regex.c实现看起来一次只能有多个字符。
答案 2 :(得分:0)
正则表达式的工作方式是实现细节。它们可以通过单向或第二方式实现。
事实上,有些语言效率低下。
如果您想了解更多信息,我可以向您推荐这篇文章:https://swtch.com/~rsc/regexp/regexp1.html