2011-07-21 7 views
31

Tengo la siguiente función escrita en Ir. La idea es que la función tenga una cadena que se le pase y devuelve la primera dirección IP IPv4 encontrada. Si no se encuentra una dirección IP, se devuelve una cadena vacía.Error de "secuencia de escape desconocida" en Ir

func parseIp(checkIpBody string) string { 
    reg, err := regexp.Compile("[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+") 
    if err == nil { 
     return "" 
    } 
    return reg.FindString(checkIpBody) 
} 

El error de tiempo de compilación que estoy recibiendo es

secuencia de escape desconocida:.

¿Cómo le puedo decir a Go que el '.' es el personaje real que estoy buscando? Pensé que escapar sería suficiente, pero aparentemente estoy equivocado.

Respuesta

63

La barra diagonal inversa \ no está siendo interpretada por el analizador de expresiones regulares, se está interpretando en el literal de cadena. Usted debe escapar de la barra invertida de nuevo:

regexp.Compile("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+") 

Una cadena delimitada con " comillas dobles se conoce como una "cadena literal interpretado" en Go. Los literales de cadena interpretados son como literales de cadena en la mayoría de los lenguajes: \ los caracteres de barra invertida no se incluyen literalmente, se usan para dar un significado especial al siguiente caracter. La fuente debe incluir \\ dos barras diagonales inversas en una fila para obtener una sola barra invertida en el valor analizado.

Como Evan Shaw pointed out in the comments, Go tiene otra alternativa que puede ser útil al escribir cadenas literales para expresiones regulares. Un "literal de cadena sin formato" es citado por ` caracteres de retroceso. No hay caracteres especiales en una cadena de texto literal, por lo que el tiempo que su patrón no incluye un acento grave puede utilizar esta sintaxis sin escapar nada:

regexp.Compile(`[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+`) 

Esto se describe en the "String literals" section of the Go spec.

+1

Muchas gracias, y un gran momento! – Nate

+24

Alternativamente, puede usar una cadena no interpretada para evitar las barras diagonales inversas dobles: 'regexp.Compile (\' [0-9] + \. [0-9] + \. [0-9] + \. [0-9 ] + \ ')' –

+2

@Evan, gran consejo. Aprendiendo un nuevo idioma ... – Nate

1

dirección IPv4 (captura precisa)

Partidos 0.0.0.0 través de 255.255.255.255

Use esta expresión regular para que coincida con los números IP accurracy.

Cada uno de los 4 números se almacena en un grupo de captura, por lo que puede acceder a ellos para su posterior procesamiento.

"(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])" 
+0

Nice complete regex. Gracias. – Nate

+1

Teniendo en cuenta la complejidad de la expresión regular, probablemente elegiría convertir la cadena en enteros y comprobar de esa manera en su lugar. Dentro de un año, dudo que recuerde muy bien los detalles de esa expresión. Ese tipo de código me ha mordido antes. Las bibliotecas Go pueden incluso tener soporte para ese tipo de control ... Por ahora solo estoy usando depender de que la cadena enviada desde el servidor sea correcta, siempre y cuando sea de 4 bytes separados por puntos ("."). – Nate

+0

Para hacerlo más fácil de leer, generalmente lo hago: 'numBlock =" (25 [0-5] | 2 [0-4] [0-9] | 1 [0-9] [0-9] | [1-9]? [0-9]) " regexPattern = numBlock +" \\. " + numBlock + "\\". + numBlock + "\\". + numBlock ' – Nashenas

Cuestiones relacionadas