将正则表达式解析为 AST 的 Python 库?

Posted

技术标签:

【中文标题】将正则表达式解析为 AST 的 Python 库?【英文标题】:Python library to parse regex into AST? 【发布时间】:2016-04-04 01:29:30 【问题描述】:

强调一下,我不想“使用正则表达式解析”——我想“将正则表达式解析为符号树”。 (搜索只找到了前者……)

我的用例:为了加快对数据库的正则表达式搜索,我想解析像 (foo|bar)baz+(bat)* 这样的正则表达式并提取所有必须出现在匹配项中的子字符串。 (在这种情况下,它只是baz,因为 foo/bar 是交替出现的,而 bat 可以出现 0 次。)

为此,我需要对正则表达式运算符/语义有所了解。 re.DEBUG 最接近:

In [7]: re.compile('(foo|bar)baz+(bat)', re.DEBUG)
subpattern 1
  branch
    literal 102
    literal 111
    literal 111
  or
    literal 98
    literal 97
    literal 114
literal 98
literal 97
max_repeat 1 4294967295
  literal 122
subpattern 2
  literal 98
  literal 97
  literal 116

但是,它只是打印出来,据我所知,c 实现并没有保留之后的结构。关于如何在不编写所有者解析器的情况下解析它的任何想法?

【问题讨论】:

如何在正则模式上使用正则表达式? @DanielSanchez 你不能用正则表达式解析正则表达式。 @BlackJack,你可以对正则表达式字符串进行正则表达式,我的意思是如果我的正则表达式有“1|2”,你可以正则表达式那个字符串。 @DanielSanchez 您可以对1|2 执行此操作,但不能对任意正则表达式执行此操作。您不能像问题所问的那样将正则表达式转换为符号树,您需要一个用于上下文无关语法的解析器,就像 Ira Baxter 的回答所解释的那样。 xkcd.com/1313 ? 【参考方案1】:

你可以只用这个:

import sre_parse
sre_parse.parse(r'(\d+)foo(.*)')

【讨论】:

【参考方案2】:

您只能使用上下文无关语法指定(经典)正则表达式:

 regex =  alternatives ;
 alternatives =  primitive  '|' alternatives  ;
 primitive = '(' regex ')' | '[' character_set ']' | ...

这意味着您不能使用正则表达式解析正则表达式(Perl 是一个例外, 但随后它的“正则表达式”超出了“经典”的范围)。

因此,要解析正则表达式,您需要构建自己的解析器并构建某种树(re.Debug 非常接近)或您希望的魔法库。

我怀疑这是最简单的部分。自己做这件事并不难。看 Is there an alternative for flex/bison that is usable on 8-bit embedded systems? 用于构建此类解析器的简单方案。

要了解正则表达式的语义(例如,找出“必要的子字符串”),您或许可以轻松构建分析器 遍历解析树,并为每个子树(自下而上)计算公共字符串。如果失败,您可能必须执行经典的 NDFA 构造然后遍历它,或者执行 NDFA 到 DFA 构造并遍历 DFA。真正的正则表达式往往包含很多杂乱无章的复杂情况,例如内置字符集、捕获组等。

“公共字符串”可能不仅仅是一个连续的字符序列,尽管您可以将其狭义地定义为这样。它可能包括几个由固定或可变长度的字符间隔分隔的常量子字符串,例如,您所需的子字符串本身可能总是可以表达为以下形式的“简单正则表达式”:

   (<character>+ ?+) <character>+

【讨论】:

是的,我希望有一些正则表达式库可以让我遍历 NDFA 或解析树;我已经使用过几次 ANTLR 之类的东西,一点也不错过...... re:“简单的正则表达式”,你用(ab+)* 之类的例子遇到了复杂性,在这些例子的末尾没有必需的子字符串那天。无论如何,感谢您的观点,这很有用(尽管会保持问题开放,以防有人有想法让我免于解析自己)

以上是关于将正则表达式解析为 AST 的 Python 库?的主要内容,如果未能解决你的问题,请参考以下文章

python - 正则表达式将数值解析为没有星号和空格的数组

Python网页解析器使用实例详解

正则表达式、xpath、BeautifulSoup和JSONPath的区别?

Python Xpath的解析,应用

Python 爬虫 解析库的使用 --- Beautiful Soup

angr 文档翻译(3):解析器引擎——符号表达式和约束求解