Diferencia entre '.' , '?' y '*' en expresiones regulares?

Respuestas:

16

Tomado directamente de Wikipedia :

? El signo de interrogación indica cero o una ocurrencia del elemento anterior. Por ejemplo, colou? R coincide con "color" y "color".

*El asterisco indica cero o más ocurrencias del elemento anterior. Por ejemplo, ab * c coincide con "ac", "abc", "abbc", "abbbc", etc.

La gran diferencia es que el asterisco coincide con cero o más ocurrencias, mientras que el signo de interrogación coincide con cero o una aparición. Compare estos dos ejemplos:

$ printf "colour\ncolor\ncolouur\n" | egrep 'colou?r'                          
colour
color
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou*r'                          
colour
color
colouur

Debido a que en colouurla letra u (el elemento anterior al calificador ?) ocurrió más de una vez, no coincide con ?, pero sí coincide con*

Ejemplo similar:

$ printf "error\neror\ner\n" | egrep 'er?or'                                   
eror
$ printf "error\neror\ner\n" | egrep 'er*or'                                   
error
eror

Desde la misma página de Wikipedia:

Coincide con cualquier carácter individual (muchas aplicaciones excluyen nuevas líneas, y exactamente qué caracteres se consideran nuevas líneas es específico del sabor, de la codificación de caracteres y de la plataforma, pero es seguro asumir que el carácter de avance de línea está incluido). Dentro de las expresiones de corchetes POSIX, el carácter de punto coincide con un punto literal. Por ejemplo, ac coincide con "abc", etc., pero [ac] solo coincide con "a", "." O "c".

En nuestro ejemplo,

$ printf "colour\ncolor\ncolouur\n" | egrep 'colo.r'                           
colour
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou.r'                          
colouur

Apropiadamente, el último se lee como match any line that has "colou", plus any character, plus letter "r"

Conclusión

Usted ha preguntado: "Sé que '*' significa todo o nada, pero no estoy seguro de si es la forma correcta de pensarlo. Por el otro '". & '?' parece lo mismo ". Como puede ver, el punto y el asterisco no son exactamente lo mismo. El punto opera en cualquier carácter que pueda estar ocupando esa posición específica, mientras que el signo de interrogación opera en el elemento anterior.

Sergiy Kolodyazhnyy
fuente
32

Puede estar confundiendo expresiones regulares con globos de shell

En la expresión regular, la sintaxis .representa cualquier carácter individual (generalmente excluyendo el carácter de nueva línea), mientras que *es un cuantificador que significa cero o más del átomo de expresión regular anterior (carácter o grupo). ?es un cuantificador que significa cero o una instancia del átomo anterior, o (en las variantes de expresiones regulares que lo admiten) un modificador que establece el comportamiento del cuantificador en no codicioso.

En los globos de shell, ?representa un solo carácter (como las expresiones regulares .) mientras que *representa una secuencia de cero o más caracteres (equivalente a expresiones regulares .*).

Un par de referencias que puede encontrar útiles son http://www.regular-expressions.info/quickstart.html y http://mywiki.wooledge.org/glob

conductor de acero
fuente
6

Nota: Examples provided are in Python.Aunque el concepto sigue siendo el mismo.

'.'es un símbolo coincidente que coincide con cualquier carácter excepto el carácter de nueva línea (esto también se puede anular con un re.DOTALLargumento en Python). Por lo tanto, también se llama como comodín .

'*'es un cuantificador (define con qué frecuencia puede ocurrir un elemento). Es la abreviatura de {0,} .

Significa "coincidencia cero o más": el grupo que precede a la estrella puede aparecer cualquier número de veces en el texto. Puede estar completamente ausente o repetirse una y otra vez.

'?'También es un cuantificador . Es la abreviatura de {0,1} .

Significa "Hacer coincidir cero o uno del grupo que precede a este signo de interrogación". También se puede interpretar como la parte que precede al signo de interrogación es opcional .

p.ej:

pattern = re.compile(r'(\d{2}-)?\d{10}')
mobile1 = pattern.search('My number is 91-9999988888')
mobile1.group()
Output: '91-9999988888'

mobile2 = pattern.search('My number is 9999988888')
mobile2.group()
Output: '9999988888'

En el ejemplo anterior '?' indica que los dos dígitos que lo preceden son opcionales. Es posible que no aparezcan o que ocurran como máximo una vez.

Diferencia entre '.' y '?':

'.'coincide / acepta / verifica cualquier carácter individual para el lugar que ocupa en la expresión regular.

p.ej:

pattern = re.compile(r'.ot')
pattern.findall('dot will identify both hot and got.')
Output: ['dot', 'hot', 'got']

'?'coincide / verifica la ocurrencia cero o única del grupo que lo precede .

Verifique el ejemplo del número de móvil.

Lo mismo va con '*'. Verificará cero o más ocurrencias del grupo que lo precede .

Combinación:

'.*': Acepta tantas secuencias como estén disponibles. Enfoque codicioso .

'.*?'Acepta la primera secuencia coincidente y se detiene. Enfoque no codicioso

Para más información, considere leer las siguientes dos preguntas ...

Dhaval Simaria
fuente