假设你想在管道上进行正则表达式搜索和提取,但模式可能跨越多行,怎么做?也许正则表达式库适用于流?
我希望使用 Python 库来完成这项工作?但是任何解决方案都可以,当然是库而不是命令行工具。
顺便说一句,我知道如何解决我当前的问题,只是寻求一个通用的解决方案。
如果不存在这样的库,为什么常规库不能与流一起使用,因为常规数学算法永远不需要向后扫描。
如果您寻求通用解决方案,您的算法将需要类似于:
match.end()
并转到步骤 2。如果没有找到匹配项,这最终可能会使用大量内存,但在一般情况下很难做得更好(考虑在唯一是最后一个字符.*x
的大文件中尝试匹配为多行正则表达式)。x
如果您对正则表达式有更多了解,您可能会遇到其他可以丢弃部分缓冲区的情况。
我解决了使用经典模式匹配搜索流的类似问题。您可能希望将我的解决方案streamsearch-py的 Matcher 类子类化并在缓冲区中执行正则表达式匹配。查看下面包含的 kmp_example.py 以获取模板。如果事实证明经典的 Knuth-Morris-Pratt 匹配就是您所需要的,那么您的问题现在就可以通过这个小型开源库解决了 :-)
#!/usr/bin/env python
# Copyright 2014-2015 @gitagon. For alternative licenses contact the author.
#
# This file is part of streamsearch-py.
# streamsearch-py is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# streamsearch-py is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
# You should have received a copy of the GNU Affero General Public License
# along with streamsearch-py. If not, see <http://www.gnu.org/licenses/>.
from streamsearch.matcher_kmp import MatcherKMP
from streamsearch.buffer_reader import BufferReader
class StringReader():
"""for providing an example read() from string required by BufferReader"""
def __init__(self, string):
self.s = string
self.i = 0
def read(self, buf, cnt):
if self.i >= len(self.s): return -1
r = self.s[self.i]
buf[0] = r
result = 1
print "read @%s" % self.i, chr(r), "->", result
self.i+=1
return result
def main():
w = bytearray("abbab")
print "pattern of length %i:" % len(w), w
s = bytearray("aabbaabbabababbbc")
print "text:", s
m = MatcherKMP(w)
r = StringReader(s)
b = BufferReader(r.read, 200)
m.find(b)
print "found:%s, pos=%s " % (m.found(), m.get_index())
if __name__ == '__main__':
main()
输出是
pattern of length 5: abbab
text: aabbaabbabababbbc
read @0 a -> 1
read @1 a -> 1
read @2 b -> 1
read @3 b -> 1
read @4 a -> 1
read @5 a -> 1
read @6 b -> 1
read @7 b -> 1
read @8 a -> 1
read @9 b -> 1
found:True, pos=5
我不相信可以在流上使用正则表达式,因为没有整条数据,您无法进行正匹配。这意味着你只会有一个可能的匹配。
但是,正如@James Henstridge 所说,您可以使用缓冲区来克服这个问题。