example - Python RegEx grupos múltiples





re.findall online (5)


Su expresión regular solo contiene un par de paréntesis (un grupo de captura), por lo que solo obtendrá un grupo en su coincidencia. Si utiliza un operador de repetición en un grupo de captura ( + o * ), el grupo se "sobrescribe" cada vez que se repite el grupo, lo que significa que solo se captura la última coincidencia.

En su ejemplo aquí, probablemente sea mejor usar .split() , en combinación con una expresión regular:

lun_q = 'Lun:\s*(\d+(?:\s+\d+)*)'
s = '''Lun: 0 1 2 3 295 296 297 298'''

r = re.search(lun_q, s)

if r:
    luns = r.group(1).split()

    # optionally, also convert luns from strings to integers
    luns = [int(lun) for lun in luns]

Me confundo devolver varios grupos en Python. Mi RegEx es este:

lun_q = 'Lun:\s*(\d+\s?)*'

Y mi cadena es

s = '''Lun:                     0 1 2 3 295 296 297 298'''`

Devuelvo un objeto coincidente y luego quiero ver los grupos, pero todo muestra el último número (258):

r.groups()  
(u'298',)

¿Por qué no devuelve grupos de 0,1,2,3,4 etc.?




Otro enfoque sería usar la expresión regular que tiene para validar sus datos y luego usar una expresión regular más específica que se dirija a cada elemento que desea extraer utilizando un iterador de coincidencia.

import re
s = '''Lun: 0 1 2 3 295 296 297 298'''
lun_validate_regex = re.compile(r'Lun:\s*((\d+)(\s\d+)*)')
match = lun_validate_regex.match(s)
if match:
    token_regex = re.compile(r"\d{1,3}")
    match_iterator = token_regex.finditer(match.group(1))
    for token_match in match_iterator:
        #do something brilliant



Si está buscando una salida como 0,1,2,3,4, etc. La respuesta simple es la siguiente.

imprimir re.findall ('\ d', s)




A veces, es más fácil sin expresiones regulares.

>>> s = '''Lun: 0 1 2 3 295 296 297 298'''
>>> if "Lun: " in s:
...     items = s.replace("Lun: ","").split()
...     for n in items:
...        if n.isdigit():
...           print n
...
0
1
2
3
295
296
297
298



Función del __call__()método de una metaclase al crear una instancia de clase

Si ha realizado la programación en Python durante más de unos pocos meses, eventualmente se encontrará con un código que se ve así:

# define a class
class SomeClass(object):
    # ...
    # some definition here ...
    # ...

# create an instance of it
instance = SomeClass()

# then call the object as if it's a function
result = instance('foo', 'bar')

Esto último es posible cuando implementas el __call__()método mágico en la clase.

class SomeClass(object):
    # ...
    # some definition here ...
    # ...

    def __call__(self, foo, bar):
        return bar + foo

El __call__()método se invoca cuando una instancia de una clase se utiliza como una llamada. Pero como hemos visto en respuestas anteriores, una clase en sí misma es una instancia de una metaclase, por lo que cuando usamos la clase como llamable (es decir, cuando creamos una instancia de ella), en realidad estamos llamando al __call__()método de metaclase . En este punto, la mayoría de los programadores de Python están un poco confundidos porque se les ha dicho que cuando crean una instancia como esta instance = SomeClass(), están llamando a su __init__()método. Algunos que han cavado un poco más profundo saben que antes __init__()hay __new__(). Bueno, hoy se está revelando otra capa de verdad, antes de que __new__()exista la metaclase __call__().

Estudiemos la cadena de llamadas al método desde la perspectiva específica de crear una instancia de una clase.

Esta es una metaclase que registra exactamente el momento anterior a la creación de una instancia y el momento en que está a punto de devolverla.

class Meta_1(type):
    def __call__(cls):
        print "Meta_1.__call__() before creating an instance of ", cls
        instance = super(Meta_1, cls).__call__()
        print "Meta_1.__call__() about to return instance."
        return instance

Esta es una clase que usa esa metaclase.

class Class_1(object):

    __metaclass__ = Meta_1

    def __new__(cls):
        print "Class_1.__new__() before creating an instance."
        instance = super(Class_1, cls).__new__(cls)
        print "Class_1.__new__() about to return instance."
        return instance

    def __init__(self):
        print "entering Class_1.__init__() for instance initialization."
        super(Class_1,self).__init__()
        print "exiting Class_1.__init__()."

Y ahora vamos a crear una instancia de Class_1

instance = Class_1()
# Meta_1.__call__() before creating an instance of <class '__main__.Class_1'>.
# Class_1.__new__() before creating an instance.
# Class_1.__new__() about to return instance.
# entering Class_1.__init__() for instance initialization.
# exiting Class_1.__init__().
# Meta_1.__call__() about to return instance.

Observe que el código anterior no hace nada más que registrar las tareas. Cada método delega el trabajo real a la implementación de sus padres, manteniendo así el comportamiento predeterminado. Dado que typees Meta_1la clase padre ( typees la metaclase padre predeterminada) y teniendo en cuenta la secuencia de ordenamiento de la salida anterior, ahora tenemos una idea de cuál sería la pseudo implementación de type.__call__():

class type:
    def __call__(cls, *args, **kwarg):

        # ... maybe a few things done to cls here

        # then we call __new__() on the class to create an instance
        instance = cls.__new__(cls, *args, **kwargs)

        # ... maybe a few things done to the instance here

        # then we initialize the instance with its __init__() method
        instance.__init__(*args, **kwargs)

        # ... maybe a few more things done to instance here

        # then we return it
        return instance

Podemos ver que el __call__()método de metaclase es el que se llama primero. Luego delega la creación de la instancia al __new__()método de la clase y la inicialización a la instancia __init__(). También es el que finalmente devuelve la instancia.

De lo anterior se desprende que a la metaclase __call__()también se le da la oportunidad de decidir si se realizará o no una llamada Class_1.__new__()o Class_1.__init__()finalmente se realizará. En el transcurso de su ejecución, podría devolver un objeto que no haya sido tocado por ninguno de estos métodos. Tomemos, por ejemplo, este enfoque para el patrón de singleton:

class Meta_2(type):
    singletons = {}

    def __call__(cls, *args, **kwargs):
        if cls in Meta_2.singletons:
            # we return the only instance and skip a call to __new__()
            # and __init__()
            print ("{} singleton returning from Meta_2.__call__(), "
                   "skipping creation of new instance.".format(cls))
            return Meta_2.singletons[cls]

        # else if the singleton isn't present we proceed as usual
        print "Meta_2.__call__() before creating an instance."
        instance = super(Meta_2, cls).__call__(*args, **kwargs)
        Meta_2.singletons[cls] = instance
        print "Meta_2.__call__() returning new instance."
        return instance

class Class_2(object):

    __metaclass__ = Meta_2

    def __new__(cls, *args, **kwargs):
        print "Class_2.__new__() before creating instance."
        instance = super(Class_2, cls).__new__(cls)
        print "Class_2.__new__() returning instance."
        return instance

    def __init__(self, *args, **kwargs):
        print "entering Class_2.__init__() for initialization."
        super(Class_2, self).__init__()
        print "exiting Class_2.__init__()."

Observemos qué sucede cuando intentamos crear un objeto de tipo repetidamente. Class_2

a = Class_2()
# Meta_2.__call__() before creating an instance.
# Class_2.__new__() before creating instance.
# Class_2.__new__() returning instance.
# entering Class_2.__init__() for initialization.
# exiting Class_2.__init__().
# Meta_2.__call__() returning new instance.

b = Class_2()
# <class '__main__.Class_2'> singleton returning from Meta_2.__call__(), skipping creation of new instance.

c = Class_2()
# <class '__main__.Class_2'> singleton returning from Meta_2.__call__(), skipping creation of new instance.

a is b is c # True




python regex