- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我目前正在使用 python 的 re
模块来搜索和捕获组。我列出了一些正则表达式,我必须编译这些正则表达式并将其与导致性能问题的大型数据集 进行匹配。
示例:
REGEXES = [
'^New York(?P<grp1>\d+/\d+): (?P<grp2>.+)$',
'^Ohio (?P<grp1>\d+/\d+/\d+): (?P<grp2>.+)$',
'(?P<year>\d{4}-\d{1,2}-\d{1,2})$',
'^(?P<year>\d{1,2}/\d{1,2}/\d{2,4})$',
'^(?P<title>.+?)[- ]+E(?P<epi>\d+)$'
.
.
.
.
]
注意:正则表达式不会相似
COMPILED_REGEXES = [re.compile(r, flags=re.I) for r in REGEXES]
def find_match(string):
for regex in COMPILED_REGEXES:
match = regex.search(string)
if not match:
continue
return match
有解决办法吗?这个想法是为了避免通过编译的正则表达式迭代来获得匹配。
最佳答案
您的任何正则表达式是否会破坏 DFA 兼容性?在您的示例中看起来不像。您可以使用 Python wrapper围绕 C/C++ DFA 实现,如 re2 ,这是 re
的替代品. re2
也将退回到使用 re
如果正则表达式与 re2
不兼容syntax , 因此它将优化所有可能的情况,并且不会在不兼容的情况下失败。
请注意 re2
是否支持(?P<name>regex)
捕获语法,但它不支持 (?P=<name>)
反向引用语法。
try:
import re2 as re
re.set_fallback_notification(re.FALLBACK_WARNING)
except ImportError:
# latest version was for Python 2.6
else:
import re
如果你有带有反向引用的正则表达式,你仍然可以使用 re2
有一些特殊注意事项:您需要将正则表达式中的反向引用替换为 .*?
, 您可能会发现错误的匹配项,您可以使用 re
过滤掉这些匹配项.在现实世界的数据中,错误匹配可能并不常见。
这是一个说明性的例子:
import re
try:
import re2
re2.set_fallback_notification(re2.FALLBACK_WARNING)
except ImportError:
# latest version was for Python 2.6
REGEXES = [
'^New York(?P<grp1>\d+/\d+): (?P<grp2>.+)$',
'^Ohio (?P<grp1>\d+/\d+/\d+): (?P<grp2>.+)$',
'(?P<year>\d{4}-\d{1,2}-\d{1,2})$',
'^(?P<year>\d{1,2}/\d{1,2}/\d{2,4})$',
'^(?P<title>.+?)[- ]+E(?P<epi>\d+)$',
]
COMPILED_REGEXES = [re.compile(r, flags=re.I) for r in REGEXES]
# replace all backrefs with .*? for re2 compatibility
# is there other unsupported syntax in REGEXES?
COMPILED_REGEXES_DFA = [re2.compile(re2.sub(r'\\d|\\g\\d|\\g\<\d+\>|\\g\<\w+\>', '.*?', r), flags=re2.I) for r in REGEXES]
def find_match(string):
for regex, regex_dfa in zip(COMPILED_REGEXES, COMPILED_REGEXES_DFA):
match_dfa = regex_dfa.search(string)
if not match_dfa:
continue
match = regex.search(string)
# most likely branch comes first for better branch prediction
if match:
return match
如果这还不够快,您可以采用多种技术将 DFA 匹配提供给 re
在处理它们时,而不是将它们存储在文件或内存中,并在它们全部收集完毕后将它们移交。
您还可以将所有正则表达式组合成一个交替组的大型 DFA 正则表达式 (r1)|(r2)|(r3)| ... |(rN)
并在生成的匹配对象上遍历您的组匹配,以尝试仅匹配相应的原始正则表达式。匹配结果对象将具有与 OP 的原始解决方案相同的状态。
# rename group names in regexeps to avoid name collisions
REGEXES_PREFIXED = [re2.sub(r'\(\?P\<(\w+)\>', r'(P<re{}_\1>'.format(idx), r) for idx, r in enumerate(REGEXES)]
# wrap and fold regexps (?P<hit0>pattern)| ... |(?P<hitN>pattern)
REGEX_BIG = ''
for idx, r in enumerate(REGEXES_PREFIXED):
REGEX_BIG += '(?P<hit{}>{})|'.format(idx, r)
else:
REGEX_BIG = REGEX_BIG[0:-1]
regex_dfa_big = re2.compile(REGEX_BIG, flags = re2.I)
def find_match(string):
match_dfa = regex_dfa_big.search(string)
if match_dfa:
# only interested in hit# match groups
hits = [n for n, _ in match_dfa.groupdict().iteritems() if re2.match(r'hit\d+', n)]
# check for false positives
for idx in [int(h.replace('hit', '')) for h in hits]
match = COMPILED_REGEXES[idx].search(string)
if match:
return match
你也可以看看pyre这是同一个 C++ 库更好维护的包装器,但不是 re
的替代品.还有一个 Python Wrapper对于RuRe ,这是我所知道的最快的正则表达式引擎。
关于NFA 的 Python 正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52753438/
我在 http://lambda-the-ultimate.org/node/2064 看到了“Glushkov NFA”这个词.搜索引擎正在返回对使用 glushkov nfa 的文章的引用,但没有
这有什么证据吗?我们怎么知道当前NFA有最小量? 最佳答案 相对于DFA minimization ,其中存在有效的方法不仅可以根据描述给定常规语言的状态数确定最小 DFA 的大小,而且可以实际计算最
给定两个不确定的有限自动机 M1 和 M2,是否有一个有效的算法来确定 M1 接受的语言是否是M2 接受的语言? 最佳答案 除非 P=NP,否则不会。如果你有这样的算法,你可以很容易地确定两个 NFA
当您阅读诸如 Regex: NFA and Thompson's algorithm 之类的帖子时一切看起来都相当简单,直到您意识到在现实生活中您不仅需要像“7”或“b”这样的直接字符,而且还需要:
我正在寻找将正则表达式转换为 NFA 的方法。我知道我们需要将正则表达式转换为解析树,然后将其转换为 NFA。我正在使用 java 脚本。有没有js工具可以直接根据给定的正则表达式生成解析树? 此外,
我正在将一组给定的正则表达式转换为单个 NFA,但我遇到了一些问题。我应该如何转换正则表达式,例如“ab.*c”(表示匹配一个“a”、一个“b”、任意数量的字符,然后是一个“c”)? 我的最终目标是将
我正在尝试开发一个模拟程序,在 Java 中执行一个非确定性有限自动机。第一个命令行参数是定义机器的文本文件。第二个参数是输入字符串。如果它接受该字符串,它会打印到标准输出“accept”,后跟一个它
Python 中是否有任何模块可以将正则表达式转换为相应的 NFA,还是我必须从头开始构建代码(通过将正则表达式从中缀转换为后缀,然后实现 Thompson's Algorithm 以获得相应的 NF
在我的词法分析器生成器中,我使用 McNaughton 和 Yamada 算法构建 NFA,其属性之一是从 I 到 J,在 J 位置用 char 标记。 因此,NFA 的每个节点都可以简单地表示为下一
我知道将正则表达式转换为 NFA,有一个算法。 但我想知道是否有一种算法可以将 NFA 转换为正则表达式。 如果有,它是什么? 如果没有,我还想知道是否所有 NFA 都可以转换为正则表达式。 是否存在
从正则表达式创建 NFA 时,我遇到了“描述每个步骤”的问题。问题如下: 将以下正则表达式转换为非确定性有限状态自动机 (NFA),清楚地描述您使用的算法的步骤: (b|a)*b(a|b) 我已经制作
我不知道这个问题是否适合问,但我绝对觉得应该问。当然,我确实在互联网和 StackOverflow 本身上看到了很多很好且内容丰富的问题、文章。但我发现所有问题或文章都遵循特定的规则或模式来解释该
我已经使用二维数组为 DFA 创建了转换表。例如,存储 10 个状态和两个转换。 transition = new int[10][2]; 但是,对于 NFA 来说,我们还有许多可能的过渡要做。下面的
是否有一个好的库可以将正则表达式转换成NFA?我看到很多关于这个主题的学术论文,它们很有帮助,但在工作代码方面却不多。 我的问题部分是出于好奇,部分是由于实际需要在我正在处理的生产系统上加速正则表达式
我在这个网站上发现了同样的问题,答案是PDF describing how to convert an NFA to a regex .但这不起作用,因为此方法有一些条件: 有从初始状态到所有其他状态
我制作了由正则表达式 3d 数组构成的 NFA,例如 (01*) 表达式。我明白了: [[FROM,TO,TRANSITION]] [['q0', 'q1', '0'], ['q1', 'q2
我正在尝试解决有关 NFA 的问题。指令如下:字母{a, b, c}。 • L1 是最后一个字符与倒数第五个字符相同的所有字符串。例如,应该接受字符串 aaacbacbca,因为倒数第五个字符和最后一
众所周知,如何从常规语言的 NFA 到最小 DFA。然而,DFA 的状态数量可能呈指数增长。 我需要的是一种减少 NFA 的方法,再次给出 NFA,但状态数较小。 T.i.我不需要结果是确定性的,但我
我正在尝试编写一个程序来接受描述正则表达式的字符串。例如: 10(0U1)* 其中 U 是联合运算符,* 是 Kleene 星号(我们也看到隐含的串联)。 我考虑过标记字符串的原子并根据运算符和操作数
我目前正在使用 python 的 re 模块来搜索和捕获组。我列出了一些正则表达式,我必须编译这些正则表达式并将其与导致性能问题的大型数据集 进行匹配。 示例: REGEXES = [ '^N
我是一名优秀的程序员,十分优秀!