Estou analisando arquivos de origem C. Quero corresponder a todas as variáveis (no formato snake-case) que terminam em _VALUE
e não começam com CANA_
, CANB_
... , CANF_
. Preciso corresponder ao nome inteiro da variável para substituição posterior.
Esta é minha configuração atual com python
import re
def signal_ending_VALUE_updater(match: re.Match) -> str:
groups = match.groupdict()
return some_operation_on(group["SIGNAL_NAME"])
REGEX=r"(?<!CAN[A-F]_)\b(?P<SIGNAL_NAME>\w+_VALUE)\b"
with open(file_path,'r') as f:
content = f.read()
content_new = re.sub(REGEX,signal_ending_VALUE_updater,content)
Infelizmente, esta regex não funciona sempre, por exemplo, se tentarmos este testacase
test=" shared->option.mem = ((canAGetScuHmiVehReqLiftModBtnSt() == CANA_SCU_HMI_VEH_REQ_LIFT_MOD_BTN_ST_PRESSED_VALUE) ||"
re.find(REGEX,test)
Retornará a variável ( CANA_SCU_HMI...
) que não quero corresponder. O que não estou considerando no regex?
A ideia por trás da regex é:
(?<!CAN[A-F]_)
: com um lookbehind negativo, garanta que a correspondência não comece com CAN seguido por uma das letras A, B, C, D, E ou F e um sublinhado (_).\b
: limite de palavras, garantindo que estamos correspondendo a palavras inteiras e não a uma parte de uma palavra(?P<SIGNAL_NAME>\w+_VALUE)
:(?P<SIGNAL_NAME>...)
: grupo combina com o nomeSIGNAL_NAME
\w
o mesmo que[a-zA-Z0-9_]
corresponderá aos nomes das variáveis do Snakecase+
garante um ou mais dos anteriores_VALUE
corresponde à string literal _VALUE no final do nome da variável.
\b
Este é novamente um limite de palavra que garante que a correspondência termine logo após o nome da variável.
Esta parte da sua regex
(?<!CAN[A-F]_)\b
afirma que esse padrãoCAN[A-F]_
não ocorre diretamente à esquerda da posição atual, seguido por um limite de palavra.Você obtém uma correspondência para este texto
CANA_SCU_HMI_VEH_REQ_LIFT_MOD_BTN_ST_PRESSED_VALUE
porque, no início dele, essa afirmação é verdadeira.O que você pode fazer é começar com um limite de palavra e então afirmar que o que está diretamente à direita não corresponde ao padrão
CAN[A-F]_
Veja uma demonstração do regex 101