RegExMatch PARA A ULTIMA LINHA DE UM CHATLOG BLOCO DE NOTAS Topic is solved

Tire suas dúvidas sobre programação em AutoHotkey

Moderator: Gio

Azarfy
Posts: 33
Joined: 25 Mar 2020, 20:21

RegExMatch PARA A ULTIMA LINHA DE UM CHATLOG BLOCO DE NOTAS

21 May 2020, 00:47

Bom sou um usuário novo e aprendiz do autohotkey, e estou com uma duvida de não saber montar o RegExMatch para ler um CHATLOG que é um bloco de notas.

a frase no caso é bem padrão, e sempre quando aparecesse eu queria que salvasse 3 dígitos de um ID né uma variável

[02:29:10] [ReportSystem]: Denuncia de [FJB]Carlin. (id: 118) contra TOIC]EfmTE.vPRS[2BTL (id: 346) | ESC

Esse é um exemplo da frase no caso eu precisaria do ultimo id: que no caso seria o id: 346, mas um problema é que o chatlog ele é preenchido conforme o jogo e as horas e eu precisaria que pegasse e armazenasse o id do ReportSystem.

Alguém pode me ajudar ou me aconselhar a melhor forma de fazer isso ?
Help me :(
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: RegExMatch PARA A ULTIMA LINHA DE UM CHATLOG BLOCO DE NOTAS

21 May 2020, 09:48

Bom dia Azarfy.

Seja bem-vindo ao fórum da comunidade do AutoHotkey.

Sempre que precisar desenvolver uma rotina RegEx você deve estudar o padrão do texto e identificar elementos que sabe que se repetirão em todas as mensagens futuras. Depois, você usa esses elementos para criar ancoras e trabalhar o texto a partir delas.

Exemplo:
No caso do texto que você postou, vejo que existem duas indicações de id. Ambas são estruturadas da mesma forma: texto fixo id:, seguido de um espaço, seguido de 3 dígitos numéricos.

Como esse padrão é o ideal para o caso e você deseja pegar a segunda ocorrência, o que tem que fazer primeiro é encontrar e depois remover a primeira ocorrência. Depois disso, você efetua a mesma busca de novo, mas somente no restante do texto.

Code: Select all

TEXTO_DA_LINHA := "[02:29:10] [ReportSystem]: Denuncia de [FJB]Carlin. (id: 118) contra TOIC]EfmTE.vPRS[2BTL (id: 346) | ESC"

PRIMEIRA_OCORRENCIA := RegExMatch(TEXTO_DA_LINHA, "id:\s\d{3,5}", TEXTO_ENCONTRADO)

TOTAL_A_REMOVER := PRIMEIRA_OCORRENCIA + StrLen(TEXTO_ENCONTRADO) ; POSICAO DA PRIMEIRA OCORRENCIA + TOTAL DE CARACTERES DA PRIMEIRA OCORRENCIA

StringTrimLeft, TEXTO_SEM_A_PRIMEIRA_OCORRENCIA, TEXTO_DA_LINHA, %TOTAL_A_REMOVER%

SEGUNDA_OCORRENCIA := RegExMatch(TEXTO_SEM_A_PRIMEIRA_OCORRENCIA, "id:\s\d{3,5}", TEXTO_ENCONTRADO_2)

MSGBOX % TEXTO_ENCONTRADO_2

:arrow: No código acima eu coloquei que o número poderia ser de 3 até 5 caracteres (você pode mudar isso se tiver certeza que ele só pode ser de 3 caracteres).

Espero ter ajudado, se ainda tiver alguma dúvida, basta posta abaixo.
Azarfy
Posts: 33
Joined: 25 Mar 2020, 20:21

Re: RegExMatch PARA A ULTIMA LINHA DE UM CHATLOG BLOCO DE NOTAS

21 May 2020, 10:38

Nossa Gio muito obrigado pela a ajuda, já deu um inicio muito importante para o que eu to precisando, funcionou, porem eu precisaria que ele leia sempre a ultima linha de um bloco de notas que contem essas informações, no caso no bloco de notas tem assim

[12:34:04] [ReportSystem]: Denuncia de [iRA]Ian.RLQ[CHQT (id: 63) contra [FJG]Flash.97[GEC] (id: 49) | me leva ate ele

[12:34:04] [ReportSystem]: Denuncia de [TJBpb]Biell.V1[BTR] (id: 162) contra [TJG]Klyn.RCP[LDA] (id: 175) | xiter

[12:34:04] [ReportSystem]: Denuncia de [MV]ThiagoMV.83[DPA] (id: 268) contra [CRN]Fabio08[AAF] (id: 262) | esc

[12:34:04] [ReportSystem]: Denuncia de MSA]Pikachu.BLT[CBF (id: 208) contra TEV]Criia.PRES[UAS (id: 153) | chutao

[12:34:04] [ReportSystem]: Denuncia de [TMV]LF.1991[PCA] (id: 190) contra [TJS]RIBE.SUP[BTR (id: 62) | esc dominio

[12:34:04] [ReportSystem]: Denuncia de [GDF]Rezin.LHP[TVP (id: 34) contra [TTI]Tigre.72[UPC] (id: 180) | ant


Eu precisaria da ultima no caso apenas do digito 180, qual a melhor forma de fazer isso ? e tem como colocar para ir fazendo uma leitura de sempre que aparecer ?
@Gio
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: RegExMatch PARA A ULTIMA LINHA DE UM CHATLOG BLOCO DE NOTAS

21 May 2020, 16:33

Você pode ler o conteúdo de um arquivo com o comando FileRead.

Em seguida, pode separar o conteúdo do arquivo linha a linha através do comando StringSplit. Este comando cria, a partir de um caractere separador (que pode ser o caractere de quebra de linha) uma série de variáveis indexadas (array), todas elas nomeadas com um nome seguido de cada número ordenador, e cada uma com o conteúdo de um campo resultante dessa separação, e de quebra ainda te dá o total de campos criados no índice 0.

Exemplo: se eu separar abc|def|ghi indicando como separador o símbolo | e como nome da array CAMPO_ eu terei como resultado a criação das seguintes variáveis:

CAMPO_1, cujo conteúdo é abc
CAMPO_2, cujo conteúdo é def
CAMPO_3, cujo conteúdo é ghi
e CAMPO_0, cujo conteúdo é 3 (porque no total o comando conseguiu criar 3 campos separando o texto pelo |).

Sendo assim, fica muito fácil acessar o último campo usando uma dereferenciação dupla da variável de CAMPO_%CAMPO_0%.

Exemplo prático: No código abaixo, vou pegar o exemplo de arquivo que você postou e vou usar o StringSplit para separar o conteúdo por linha (através do caractere separador de linhas, chamado linefeed e cujo indicador no AutoHotkey é `n). Depois, através do valor contido em LINHA_0, vou identificar qual foi a última linha e daí vou aplicar a mesma lógica da rotina do post acima.

Code: Select all

CONTEUDO_DO_ARQUIVO =
(
[12:34:04] [ReportSystem]: Denuncia de [iRA]Ian.RLQ[CHQT (id: 63) contra [FJG]Flash.97[GEC] (id: 49) | me leva ate ele

[12:34:04] [ReportSystem]: Denuncia de [TJBpb]Biell.V1[BTR] (id: 162) contra [TJG]Klyn.RCP[LDA] (id: 175) | xiter

[12:34:04] [ReportSystem]: Denuncia de [MV]ThiagoMV.83[DPA] (id: 268) contra [CRN]Fabio08[AAF] (id: 262) | esc

[12:34:04] [ReportSystem]: Denuncia de MSA]Pikachu.BLT[CBF (id: 208) contra TEV]Criia.PRES[UAS (id: 153) | chutao

[12:34:04] [ReportSystem]: Denuncia de [TMV]LF.1991[PCA] (id: 190) contra [TJS]RIBE.SUP[BTR (id: 62) | esc dominio

[12:34:04] [ReportSystem]: Denuncia de [GDF]Rezin.LHP[TVP (id: 34) contra [TTI]Tigre.72[UPC] (id: 180) | ant
)

StringSplit, LINHA_, CONTEUDO_DO_ARQUIVO, `n

TEXTO_DA_LINHA := LINHA_%LINHA_0%

PRIMEIRA_OCORRENCIA := RegExMatch(TEXTO_DA_LINHA, "id:\s\d{1,5}", TEXTO_ENCONTRADO)

TOTAL_A_REMOVER := PRIMEIRA_OCORRENCIA + StrLen(TEXTO_ENCONTRADO) ; POSICAO DA PRIMEIRA OCORRENCIA + TOTAL DE CARACTERES DA PRIMEIRA OCORRENCIA

StringTrimLeft, TEXTO_SEM_A_PRIMEIRA_OCORRENCIA, TEXTO_DA_LINHA, %TOTAL_A_REMOVER%

SEGUNDA_OCORRENCIA := RegExMatch(TEXTO_SEM_A_PRIMEIRA_OCORRENCIA, "id:\s\d{3,5}", TEXTO_ENCONTRADO_2)

MSGBOX % TEXTO_ENCONTRADO_2

:arrow: Percebi que o id pode ser formado a partir de apenas 2 dígitos (antes pensei que era nó mínimo 3). Atualizei o RegEx para permitir uma sequência composta de 1 até 5 números. Isso demonstra uma característica importante: sempre analise bem a estrutura do texto alvo. Um único exemplo de linha não era o bastante.

:arrow: No seu caso você colocaria o FileRead para ler o conteúdo do arquivo para dentro da variável CONTEUDO_DO_ARQUIVO. Como eu não tenho um arquivo e nem o caminho dele aqui, fiz o exemplo com o conteúdo colocado diretamente na variável.
Azarfy
Posts: 33
Joined: 25 Mar 2020, 20:21

Re: RegExMatch PARA A ULTIMA LINHA DE UM CHATLOG BLOCO DE NOTAS

21 May 2020, 19:43

Obrigado por responder @Gio , porem dessa vez não deu certo, eu esqueci de compartilhar o arquivo e as outras informações contidas nele, alem da linda de ReportSystem tem outras linhas que não deixou funcionar como o anterior.

Esse é o link do do bloco de notas, no meu caso do Chat Log, https www.mediafire.com /file/2uzu9ls7dsqfodw/chatlog.txt/file Broken Link for safety

E o diretório ate ele seria

Code: Select all

FileRead, TEXTO_DA_LINHA, C:\Users\alanb\Documents\GTA San Andreas User Files\SAMP/chatlog.txt
Porem eu não consegui estabilizar para ler o Ultimo ReportSystem do arquivo.

Code: Select all

Tab:

FileRead, TEXTO_DA_LINHA, C:\Users\alanb\Documents\GTA San Andreas User Files\SAMP/chatlog.txt
PRIMEIRA_OCORRENCIA := RegExMatch(TEXTO_DA_LINHA, "id:\s\d{1,3}", TEXTO_ENCONTRADO)
TOTAL_A_REMOVER := PRIMEIRA_OCORRENCIA + StrLen(TEXTO_ENCONTRADO) ; POSICAO DA PRIMEIRA OCORRENCIA + TOTAL DE CARACTERES DA PRIMEIRA OCORRENCIA
StringTrimLeft, TEXTO_SEM_A_PRIMEIRA_OCORRENCIA, TEXTO_DA_LINHA, %TOTAL_A_REMOVER%
SEGUNDA_OCORRENCIA := RegExMatch(TEXTO_SEM_A_PRIMEIRA_OCORRENCIA, "id: \s\d{1,3}", TEXTO_ENCONTRADO_2)
  
SendInput tO id reportado é o ID: %TEXTO_ENCONTRADO_2%{enter}
return

Assim foi a maneira que consegui mais ou menos, porem ele lê apenas o primeiro report contido no arquivo, eu precisaria cada vez que apertar TAB, ele me mostrar o ultimo reportsystem contido no Chatlog. Dês de já Gio, sou muito grato pela a ajuda, participo a um tempo no fórum mas nunca criei coragem de abrir uma duvida, estou muito contente com o resultado e admirado pelo o seu trabalho, obrigado !!
User avatar
Gio
Posts: 1247
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: RegExMatch PARA A ULTIMA LINHA DE UM CHATLOG BLOCO DE NOTAS  Topic is solved

21 May 2020, 20:24

Boa noite Azarfy.

A existência de outros possíveis tipos de linhas no arquivo é uma informação imprescindível para o desenvolvimento da rotina. Veja que sem saber disso, supus que a última linha do arquivo era de fato a linha ser usada sempre.

De qualquer forma, uma vez que o RegEx está pronto, basta um pequeno ajuste na lógica do script para isolar última linha ReportSystem corretamente.

Code: Select all

FileRead, CONTEUDO_DO_ARQUIVO, C:\Users\alanb\Documents\GTA San Andreas User Files\SAMP\chatlog.txt

StringSplit, LINHA_, CONTEUDO_DO_ARQUIVO, `n

Loop % LINHA_0
{
	If (InStr(LINHA_%A_Index%, "[ReportSystem]:"))
	{
		ULTIMA_LINHA_REPORT := LINHA_%A_index%
	}
}

TEXTO_DA_LINHA := ULTIMA_LINHA_REPORT

PRIMEIRA_OCORRENCIA := RegExMatch(TEXTO_DA_LINHA, "id:\s\d{1,5}", TEXTO_ENCONTRADO)

TOTAL_A_REMOVER := PRIMEIRA_OCORRENCIA + StrLen(TEXTO_ENCONTRADO) ; POSICAO DA PRIMEIRA OCORRENCIA + TOTAL DE CARACTERES DA PRIMEIRA OCORRENCIA

StringTrimLeft, TEXTO_SEM_A_PRIMEIRA_OCORRENCIA, TEXTO_DA_LINHA, %TOTAL_A_REMOVER%

SEGUNDA_OCORRENCIA := RegExMatch(TEXTO_SEM_A_PRIMEIRA_OCORRENCIA, "id:\s\d{3,5}", TEXTO_ENCONTRADO_2)

MSGBOX % TEXTO_ENCONTRADO_2

:arrow: O que fizemos no código acima foi o seguinte: Já que queremos a informação da última linha ReportSystem, devemos fazer um loop entrando linha a linha no arquivo e verificando quais delas contém a expressão [ReportSystem]:. Isso foi feito usando a função InStr(). Sempre que encontrarmos uma linha com essa expressão, nós salvamos ela em uma mesma variável. Como o loop entra nas linhas ordenadamente (da primeira até a última, ou seja, de cima para baixo no arquivo) podemos reescrever a variável sempre que a expressão for encontrada, o que fará com que ela finde contendo apenas o texto da última linha que tiver a expressão. Com isso teremos isolado a última linha que contém a expressão [ReportSystem]:.

Depois disso, basta aplicar o algoritmo com as expressões RegEx para isolar o id.

Return to “Ajuda e Suporte Geral”

Who is online

Users browsing this forum: No registered users and 46 guests