¿Expresión regular en secuencia en lugar de cadena?

Supongamos que desea realizar una búsqueda de expresiones regulares y extraer en una canalización, pero el patrón puede cruzar varias líneas. ¿Cómo hacerlo? ¿Tal vez una biblioteca de expresiones regulares funciona para una transmisión?

Espero hacer este trabajo usando la biblioteca de Python? Pero cualquier solución estará bien, una biblioteca, no una herramienta de línea cmd, por supuesto.

Por cierto, sé cómo resolver mi problema actual, solo buscando una solución general.

Si no existe tal biblioteca, el motivo por el cual la biblioteca normal no puede funcionar con la transmisión dado el algoritmo matemático regular nunca necesita una exploración hacia atrás.

Si está buscando una solución general, su algoritmo tendría que verse como:

  1. Lea una parte de la secuencia en un búfer.
  2. Buscar la expresión regular en el buffer.
  3. Si el patrón coincide, haga lo que quiera con la coincidencia, descarte el inicio del búfer hasta match.end() y vaya al paso 2.
  4. Si el patrón no coincide, extienda el búfer con más datos del flujo

Esto podría terminar usando una gran cantidad de memoria si no se encuentran coincidencias, pero es difícil hacerlo mejor en el caso general (considere la posibilidad de hacer coincidir .*x como una expresión regular de varias líneas en un archivo grande donde la única x es la último personaje).

Si conoce más sobre la expresión regular, puede tener otros casos en los que puede descartar parte del búfer.

Resolví un problema similar para buscar una secuencia utilizando la coincidencia de patrones clásica. Es posible que desee crear una subclase de la clase Matcher de mi solución streamsearch-py y realizar una coincidencia de expresiones regulares en el búfer. Echa un vistazo a la kmp_example.py incluido para una plantilla. Si resulta que la coincidencia clásica de Knuth-Morris-Pratt es todo lo que necesita, entonces su problema se resolvería ahora mismo con esta pequeña biblioteca de código abierto 🙂

 #!/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 . 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() 

la salida es

 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 

No creo que sea posible usar una expresión regular en un flujo, porque sin una pieza completa de datos, no se puede hacer una coincidencia positiva. Esto significa que solo tendrías una coincidencia probable.

Sin embargo, como lo dijo @James Henstridge, podrías usar los buffers para superar esto.