×

Langue

Fermer
Atelier 801
  • Forums
  • Dev Tracker
  • Connexion
    • English Français
      Português do Brasil Español
      Türkçe Polski
      Magyar Română
      العربية Skandinavisk
      Nederlands Deutsch
      Bahasa Indonesia Русский
      中文 Filipino
      Lietuvių kalba 日本語
      Suomi עברית
      Italiano Česky
      Hrvatski Slovensky
      Български Latviešu
      Estonian
  • Langue
  • Forums
  • /
  • Transformice
  • /
  • Modules
  • /
  • [Tutorial] string.gsub
[Tutorial] string.gsub
Bolodefchoco
« Sénateur »
1515635040000
    • Bolodefchoco#0095
    • Profil
    • Derniers messages
    • Tribu
#1
  6

string.gsub(texto, padrao, substituicao[, quantidade_substituicao])
texto:gsub(padrao, substituicao[, quantidade_substituicao])

*Note e adote: Os parâmetros em [ ] são opcionais


ㅤstring.gsub é uma função por vezes desprezada durante a aprendizagem da linguagem Lua e/ou biblioteca string.
ㅤÉ uma função poderosa e que pode ser utilizada de várias maneiras: substituição, identificação, correspondência, etc...

ㅤA forma mais simples de utilizar a função é substituir um texto por outro.

Code Lua

1
2
3
4
5
6
7
8
local meu_nome = "Ikke mon"
--> Encontrar a cadeia "mon" na variável meu_nome e substituir por "pokémon"
--> Note que "pokémon" poderia ser escrito "poké%1". Por quê?
-->> %[0-9] tem o valor da captura no campo _padrao_;
-->> ou seja, %1='mon' em _substituicao_
meu_nome = string.gsub(meu_nome, "mon", "pokémon")
--> Ikke pokémon
print(meu_nome)

ㅤVocê também poderá criar um limite de substituições: talvez você não queira que o texto todo seja afetado pela função.
Code Lua

1
2
3
4
5
local minha_banana = "a banana vai ser assada kakaka"
--> Você pode querer substituir apenas 6 letras 'a' por 'o'
minha_banana = string.gsub(minha_banana, "a", "o", 6)
--> o bonono voi ser ossada kakaka
print(minha_banana)

ㅤVocê talvez queira fazer algo ainda mais maluco e alterar uma captura sim e outra não, uma sim e outra não, assim consecutivamente... É fácil! Basta utilizarmos uma função no parâmetro _substituicao_
Code Lua

1
2
3
4
5
6
7
8
9
10
11
12
local minhas_frutinha = "bananinha abacatinho uvazinha"
local substituicoes = 0
--> Desejo que as letras 'a' em minhas_frutinha sejam uma 'u'
--> Mas apenas quando _substituicoes_ for um número par (2, 4, 6) [uma não, uma sim, ...]
minhas_frutinha = string.gsub(minhas_frutinha , "a", function(captura)
substituicoes = substituicoes + 1
if substituicoes % 2 == 0 then -- Verifica se a divisão por 2 tem resto 0, ou seja, par
return "u"
end
end)
--> banuninha ubacutinho uvazinhu
print(minhas_frutinha)

ㅤAgora ciente das possibilidades até agora com a função string.gsub, você possa se perguntar sobre a utilização de padrões no campo _padrao_. Que tal algo simples?
Code Lua

1
2
3
4
5
6
7
8
9
10
11
12
--> A letra "u" em binário é escrito como "01110101" e temos o seguinte binário abaixo
local meu_binario = "0100"
--> Observe o padrão: 0 "1" 1 "1" 0 "1" 0 "1".. Depois de cada caractere, há um número "1".
--> Podemos afirmar que o padrão é o número capturado junto ao número "1"
-->> Com o conhecimento de padrões, sabemos que %d = um número qualquer
-->> Substituímos esse número por ele mesmo seguido de "1".
-->> Note que foi utilizado %1, afinal não sabemos se é um 0 ou 1, logo, utilizamos %1 = captura:
-->>> Em meu_binario temos 0, 1, 0, 0. Os 4 são números, mas não são os mesmos números.
-->>> Poderíamos utilizar "0", "01" se fossem apenas números 0 em meu_binario.
meu_binario = string.gsub(meu_binario , "%d", "%11")
--> 01110101
print(meu_binario)

ㅤÉ importante notar que se o parâmetro _substituicao_ for um método (função que não retorna algum valor), o valor retornado para substituição do padrão será a própria captura:
Code Lua

1
2
3
4
5
6
7
8
9
10
11
12
local teste = "abcdefg"
--> teste:gsub também é possível. Lembrese: texto:gsub(...)
--> Note que utilizamos o padrão ".", que significa caractere por caractere: a,b,c,d,e,f,g
teste = teste:gsub(".", function(captura)
-- Imprimirá a,b,c,d,e,f,g. Um de cada vez...
print(captura)
-- O retorno abaixo não é necessário, porque a captura é retornada
--- automaticamente quando nada é, de fato, retornado
-- return captura
end)
--> O valor de teste continua o mesmo
print(teste)

ㅤCom a anotação acima, podemos criar coisas realmente úteis que teriam a mesma funcionalidade que a função string.gmatch. Um exemplo disso é separar palavra por palavra:
Code Lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
local palavras = "!give cheese Bolodefchoco"
--> Você poderia utilizar
local tabela_palavras = {}
-->> Assuma [^%s]+ como "[=nao=] ^=começo %s=espaço +=vários, não começa com espaço várias palavras
-->> '!give' não começa com espaço, mas acaba até o próximo espaço
-->> 'cheese' não começa com espaço, mas acaba até o próximo espaço
-->> 'Bolodefchoco' não começa com espaço, mas acaba até o próximo espaço ou fim da string
for palavra in string.gmatch(palavras, "[^%s]+") do
-- nome[#nome + 1] = valor funciona como o table.insert(nome, valor);
--- porém mais leve durante a execução
tabela_palavras[#tabela_palavras + 1] = palavra
end
-- "!give", "cheese", "Bolodefchoco"
print(tabela_palavras[1]) print(tabela_palavras[2]) print(tabela_palavras[3])

tabela_palavras = {}
--> Mas você também pode utilizar a função string.gsub!!!!
palavras:gsub("[^%s]+",function(palavra)
tabela_palavras[#tabela_palavras + 1] = palavra
end)
-- "!give", "cheese", "Bolodefchoco"
print(tabela_palavras[1]) print(tabela_palavras[2]) print(tabela_palavras[3])

ㅤObserve o que você pode fazer:
Code Lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
--> Que padrão podemos encontrar abaixo?
local adjetivos = "o bolo é legal e também é carinhoso e é cheiroso, mas não é bonito"
--> Isso mesmo, amiguinhos. Os adjetivos procedem o verbo "é"
--> Que tal colocarmos todos os adjetivos numa tabela?

local meus_adjetivos = {}
string.gsub(adjetivos, " é (%w+)", function(adj) meus_adjetivos[#meus_adjetivos+1] = adj end)

--> Um loop para printar todos os adjetivos
for k,v in next, meus_adjetivos do
--[[
legal
carinhoso
cheiroso
bonito
]]
print(v)
end
Code Lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
--> Fazer algo tipo o gmatch ali em cima
string.split = function(texto, padrao)
local retornar = {}
texto:gsub(padrao,function(captura)
retornar[#retornar + 1] = captura
end)
return retornar
end

local pisos_mapa = {}
eventNewGame = function()
--> Temos um xml, o que podemos extrair dele?
local xml_mapa = (tfm.get.room.xmlMapInfo or {}).xml or ""

pisos_mapa = {}
local atributos_piso = {}
--> O segundo parâmetro " _ " é desprezível para que possamos utilizar %[0-9]
--> Criamos uma função para evitar a criação repetitiva de funções anônimas (heavy code)
local atribuir_valor = function(nome,_,valor)
--> O split vai dividir numa nova tabela se o valor estiver com virgulas
--> Exemplo: P="1,2,3,3,4,4" vira P = {1,2,3,3,4,4} e V="1" vira V=1
atributos_piso[nome] = (valor:find(",") and string.split(valor, "[^,]+") or tonumber(valor) or valor)
end

string.gsub(xml_mapa, "<S (.-)/>", function(atributos)
atributos_piso = {}
--> O padrão abaixo é:
--> Captura 1: números (até negativos) ou letras
--> Captura 2 (desprezível): aspas simples ou duplas ' ". Valor em %2
--> Captura 3: tudo entre a captura 2 e outro encontro da captura 2
--> 1 = 2 3 2
string.gsub(atributos, "([%-%w]+)=([\"'])(.-)%2", atribuir_valor)
pisos_mapa[#pisos_mapa + 1] = atributos_piso
end)

--> Agora vamos nos divertir e colocar um piso de nuvem em cima de cada piso do mapa
for k,v in next, pisos_mapa do
--k = Z do piso
--v = propriedades do piso
tfm.exec.addPhysicObject(k, v.X, v.Y, {
type = 8,
width = v.L,
height = v.H,
friction = v.P[3],
restitution = v.P[4],
angle = v.P[5],
miceCollision = (v.c==1 or v.c==3) or ((v.c==4 or v.c==2) and false),
groundCollision = (v.c==2 or v.c==1) or ((v.c==4 or v.c==3) and false)
})
end
end
Code Lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
--> Que tal transformar os "pq" abaixo em por que, porque, porquê e por quê?!
local meu_textao = [[
Todos riam muito e ninguém me dizia o pq.
Gostaria de saber os pq de ter sido mandada embora.
Você não comeu? Pq?
O menino foi embora e nem disse pq.
Choro pq machuquei o pé.
Ela não foi à escola pq estava chovendo.
Pq você não foi dormir?
Pq não posso sair com meus amigos?
]]

meu_textao = meu_textao:gsub("[^\n]+",function(linha)
return linha:gsub(" o(s-) pqs-", function(plural)
plural = plural=="s" and plural or ""
return " o" .. plural .. " porquê" .. plural
end):gsub("([Pp])q([%?.])", "%1or quê%2"):gsub("([Pp])q (.-) ?%?",function(p, conteudo)
return p.."or" .. (conteudo:find("pq") and "" or " ") .. "que ".. conteudo .."?"
end):gsub("([Pp])q", "porque")
end)

--[[ Índice de acertos: 80%, mas no teste o índice foi de 100%
Todos riam muito e ninguém me dizia o porquê.
Gostaria de saber os porquês de ter sido mandada embora.
Você não comeu? Por quê?
O menino foi embora e nem disse por quê.
Choro porque machuquei o pé.
Ela não foi à escola porque estava chovendo.
Por que você não foi dormir?
Por que não posso sair com meus amigos?
]]
print(meu_textao)


Dernière modification le 1515690540000
Mescouleur
« Citoyen »
1515645840000
    • Mescouleur#0000
    • Profil
    • Derniers messages
#2
  0
*-* whoaaa
Rufflesdqjo
« Citoyen »
1515668460000
    • Rufflesdqjo#0095
    • Profil
    • Derniers messages
    • Tribu
#3
  0
Lindo tutorial!
Jon
« Consul »
1515675120000
    • Jon#9169
    • Profil
    • Derniers messages
#4
  0
Ótimo tutorial
Bolodefchoco
« Sénateur »
1515677340000
    • Bolodefchoco#0095
    • Profil
    • Derniers messages
    • Tribu
#5
  0
Rufflesdqjo a dit :
Lindo tutorial!

Obrigado!
Jooonnnnnnnn a dit :
Ótimo tutorial

Obrigado!

Acabei de adicionar um tradutor de "pq" para "porque", "porquê", "por que" e "por quê". (último código)
Kanskje
« Sénateur »
1515679320000
    • Kanskje#5156
    • Profil
    • Derniers messages
    • Tribu
#6
  0
muito bom parabens. um dia ainda vou aprender lua
Bolodefchoco
« Sénateur »
1515679560000
    • Bolodefchoco#0095
    • Profil
    • Derniers messages
    • Tribu
#7
  0
Kaldt a dit :
muito bom parabens. um dia ainda vou aprender lua

O que não falta na seção é tutorial. Leia todos e estará preparado! :D
Hydroper
« Citoyen »
1515686700000
    • Hydroper#0528
    • Profil
    • Derniers messages
    • Tribu
#8
  0
é (%w+) caçaria pé de ..., too!

Really nice!
Bolodefchoco
« Sénateur »
1515690540000
    • Bolodefchoco#0095
    • Profil
    • Derniers messages
    • Tribu
#9
  0
Profiver a dit :
é (%w+) caçaria pé de ..., too!

Really nice!

Consertei
Rianmojang1
« Citoyen »
1515709320000
    • Rianmojang1#0000
    • Profil
    • Derniers messages
    • Tribu
#10
  0
Ótimo tutorial, muito bem explicado
como esperado do bolo ^^
Bolodefchoco
« Sénateur »
1515712800000
    • Bolodefchoco#0095
    • Profil
    • Derniers messages
    • Tribu
#11
  0
Rianmojang1 a dit :
Ótimo tutorial, muito bem explicado
como esperado do bolo ^^

Grato
Bortverde
« Consul »
1517055900000
    • Bortverde#0015
    • Profil
    • Derniers messages
    • Tribu
#12
  0
Bem interessante, bom tópico
Onde você utilizaria ele em um module? Além de zoar com o nick do Ikkemon kkk
Bolodefchoco
« Sénateur »
1517073600000
    • Bolodefchoco#0095
    • Profil
    • Derniers messages
    • Tribu
#13
  0
Bortverde a dit :
Bem interessante, bom tópico
Onde você utilizaria ele em um module? Além de zoar com o nick do Ikkemon kkk

kkkk clássico
string.gsub é realmente muito útil. De forma visual, nem tanto para um módulo, mas no sistema é bastante utilizado. Talvez você esteja mais familiarizado com o termo 'string.replace' em outras linguagens.

No penúltimo exemplo eu consigo capturar todos os pisos e todas as propriedades de cada um e colocar numa tabela e isso é útil pra muita coisa.
Na source do #grounds, 'gsub' é utilizado 67 vezes

https://image.prntscr.com/image/ymBCrN3AR3aiFv8GO7l10A.png


@No código está sem o '.' porque fiz algo pra otimização, mas é a mesma função

Mais um exemplo: pego a posição de todas as tocas no mapa e quando alguém encostar, será shaman
Code Lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
math.pythag = function(x1,y1,x2,y2,range)
return (x1-x2)^2 + (y1-y2)^2 <= (range^2)
end

local holes = {}
eventNewGame = function()
holes = {}

local coordinates = {}

local xml = (tfm.get.room.xmlMapInfo or {}).xml or ""
xml:gsub("<T (.-)/>", function(decorations)
coordinates = {}
decorations:gsub("([%-%w]+)=([\"'])(.-)%2", function(tag, _, value)
coordinates[tag] = tonumber(value)
end)
holes[#holes + 1] = coordinates
end)

end

eventPlayerTouchedHole = function(playerName)
tfm.exec.setShaman(playerName)
end

eventLoop = function()
for k, v in next, tfm.get.room.playerList do
for i, j in next, holes do
if math.pythag(v.x, v.y, j.X, j.Y, 30) then
eventPlayerTouchedHole(k)
end
end
end
end

tfm.exec.disableAutoNewGame()
tfm.exec.disableAutoShaman()
tfm.exec.newGame('<C><P /><Z><S><S L="121" X="76" H="137" Y="339" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S L="647" X="389" H="89" Y="408" T="0" P="0,0,0.3,0.2,0,0,0,0" /><S L="86" X="628" H="193" Y="289" T="0" P="0,0,0.3,0.2,0,0,0,0" /></S><D><T Y="189" X="743" /><T Y="391" X="751" /><T Y="252" X="70" /><DS Y="174" X="594" /></D><O /></Z></C>')

Dernière modification le 1517076060000
Gamedroit
« Citoyen »
1519768200000
    • Gamedroit#3347
    • Profil
    • Derniers messages
    • Tribu
#14
  0
credo mds, por que só não bota string:gsub(valor original, novo valor) '-' esse function ai desnecessária no gsub
Bolodefchoco
« Sénateur »
1519781100000
    • Bolodefchoco#0095
    • Profil
    • Derniers messages
    • Tribu
#15
  0
Contistente3 a dit :
credo mds, por que só não bota string:gsub(valor original, novo valor) '-' esse function ai desnecessária no gsub

wtf? vc leu? :v

a função ajuda MT
Admiire_me
« Citoyen »
1594085760000
    • Admiire_me#6770
    • Profil
    • Derniers messages
#16
  0
eu nao sei ainda como mudar o background do mapa :(

Ótimo tópico! Parabéns bolo.
Jp_darkuss
« Citoyen »
1594384500000
    • Jp_darkuss#4806
    • Profil
    • Derniers messages
#17
  0
Bem que a Staff do TFM poderia usar o string.gsub para transformar palavrões em hashtags, como no Roblox, em vez de impedir que os Brs converssassem no chat En. ;-;
Bloonshack
« Sénateur »
1596986820000
    • Bloonshack#0000
    • Profil
    • Derniers messages
#18
  0
Me ajudou muito, belo tópico ;)
  • Forums
  • /
  • Transformice
  • /
  • Modules
  • /
  • [Tutorial] string.gsub
© Atelier801 2018

Equipe Conditions Générales d'Utilisation Politique de Confidentialité Contact

Version 1.27