Mi patrón Regex:
^(?<timestamp>[a-zA-Z]{3} [0-9]{1,2} [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\.[0-9]{1,6}) (?<levelname>[AZ]) ?(ERR:)? ?(?<source>\[.*\])? (?<message>.*)Test_String_1 = "25 de octubre 14:24:29.700799 [Sistema] conectado"
Salida según mi patrón de expresiones regulares:
Match groups: timestamp Oct 25 14:24:29.700799 levelname I source [System] message ConnectedTest_String_2 = "25 de octubre 14:24:30.315344 E ERR: [[Señal]] Memoria compartida válida!"
Salida según mi patrón de expresiones regulares:
Match groups: timestamp Oct 25 14:24:30.315344 levelname E source [[Signal]] message Valid Shared Mem!Sin embargo, espero los siguientes resultados para Test_String_1 y Test_String_2:
Test_String_1:
Match groups: timestamp Oct 25 14:24:29.700799 levelname I source System message ConnectedTest_String_2:
Match groups: timestamp Oct 25 14:24:30.315344 levelname E source Signal message Valid Shared Mem!¿Qué cambios debo hacer en mi patrón de expresiones regulares para obtener el resultado esperado? Estoy usando https://rubular.com/ para pruebas de expresiones regulares.
[Editar]: Test_String_3 = "25 de octubre 14:24:29.653900 D Conexión rechazada"
Rendimiento esperado:
Match groups: timestamp Oct 25 14:24:29.653900 levelname D source message Connection refusedCreo que esto es lo que quieres
^(?<timestamp>[a-zA-Z]{3} [0-9]{1,2} [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\.[0-9]{1,6}) (?<levelname>[AZ]) ?(ERR:)? ?(\[*(?<source>\w*)\]*) (?<message>.*) los corchetes deben envolver el campo source .
Puede hacer coincidir la siguiente expresión regular.
^(?P<timestamp>[JFMASOND][az]{2} [0123]\d [012]\d(?::[0-5]\d){2}\.\d{6}\b) (?P<levelname>[AZ]) +(?:[AZ]+: +)?(?:\[+(?P<source>[A-Za-z]+)\]+)? *(?P<message>.+) Tenga en cuenta que he hecho que la source del grupo de captura sea opcional.
Dependiendo de los requisitos, es posible que sea necesario realizar algunos ajustes. Supuse, por ejemplo, que el grupo de captura de source contendría una sola palabra y si no había espacios entre el nombre del levelname y la source (o mensaje), estaría compuesto por una o más letras mayúsculas seguidas de dos puntos, como en el segundo ejemplo ( 'ERR:' ). También hice suposiciones sobre qué tan riguroso debe especificarse el formato de timestamp de tiempo y qué grupos de captura deben hacerse opcionales. Por supuesto, estas fueron solo conjeturas sobre la especificación, ya que no se detallaron en la pregunta.
La expresión regular se puede dividir de la siguiente manera. Tenga en cuenta que he puesto espacios individuales en las clases de caracteres ( [ ] ) simplemente para hacerlos visibles al lector. He probado esto con Python (para el cual se escriben clases de caracteres con nombre (?P<name>....) , pero también funcionaría en Ruby.
^ # match beginning of string (?P<timestamp> # begin 'timestamp' capture group [JFMASOND] # match a cap letter in the char class [az]{2} # match two lowercase letters [ ] # match a space [0123]\d # match a digit in the char class then any digit [ ] # match a space [012]\d # match a digit in the char class then any digit (?: # begin a non-capture group : # match a colon [0-5]\d # match a digit in the char class then any digit ){2} # end non-capture group and execute it twice \. # match a period \d{6} # match 6 digits \b # match a word boundary ) # end timestamp capture group (?P<levelname> # begin 'levelname' capture group [AZ])[ ]+ # match a capital letter then >= 1 spaces ) # end 'levelname' capture group (?:[AZ]+:[ ]+)? # optionally match >= 1 capital letters # then >= 1 spaces (?: # begin non-capture group \[+ # match one or more left brackets (?P<source> # begin capture group 'source' [A-Za-z]+ # match >= 1 chars in char class ) # end capture group 'source' \]+ # match one or more right brackets )? # end non-capture group and make optional [ ]* # match >= 0 spaces (?P<message>.+) # match rest of line and save to capture # group 'message'