Jump to content




[SOLVED] string.gmatch seems to steal letters

turtle lua

11 replies to this topic

#1 BrunoZockt

  • Members
  • 28 posts
  • LocationHamburg, Germany

Posted 12 July 2018 - 01:05 AM

Hey Guys,

after some time I was finally brave enough to work on my turtle program again but came across an issue I can't figure out myself. The complete program: https://pastebin.com/fptxKN9n
Sorry for the title by the way, I don't know how to put it in a few words.

I basically just want to print out the table variables.ignor.
Spoiler
But I need to do it with my own custom function so that the words wrap around at the end of the screen.
The custom function, although irrelevant for this thread since it works and I've used it for years:
Spoiler
What is relevant, is that my function only takes a table as input. Now you might think: "What is his problem?? He wants to print a table and thats what his function does, right?" Well, hold on. I also want to remove all the parts of the strings that say "minecraft:". I already have a function that should achieve this, even though it was designed for a different purpose:
function Splitter(inputstr, sep)
  if inputstr == nil then
	return nil
  elseif sep == nil then
	sep = " "
  end
  local t={} ; i=1
  for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
	t[i] = str
	i = i + 1
  end
  return t
end
This function only takes a string as input, which is why I use textutils.serialize on my table before feeding it forward to the Splitter.
My complete command looks like this:
printWrapped(Splitter(textutils.serialize(variables.ignor), '\n  "minecraft:'), 18, 4, w-18)
And somewhere in here seems to be the mistake because instead of a somehow expected result, I get
{ s o , obbl s o , d , l v , low g_l v , w , low g_w , }

I hope you can show me what I did wrong and give a short explanation.
Thanks in advance,
Bruno

Edited by BrunoZockt, 14 July 2018 - 11:59 PM.


#2 KingofGamesYami

  • Members
  • 2,969 posts
  • LocationUnited States of America

Posted 12 July 2018 - 01:22 AM

I think string.gsub( str, "minecraft:", "" ) would work much better in this case.

#3 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 6,971 posts
  • LocationTasmania (AU)

Posted 12 July 2018 - 02:17 AM

View PostBrunoZockt, on 12 July 2018 - 01:05 AM, said:

I hope you can show me what I did wrong and give a short explanation.

You're not matching the literal string "minecraft:", you're matching any of the characters contained within it:

"([^"..sep.."]+)"

Yami's gsub is indeed much simpler.

https://www.lua.org/pil/20.2.html

Also, you're making two separate statements here. One defines "t" as a local, one defines "i" as a global:

local t={} ; i=1

If you wanted to make them both local within the space of a single line, you'd do:

local t, i = {}, 1

http://lua-users.org...ignmentTutorial

#4 BrunoZockt

  • Members
  • 28 posts
  • LocationHamburg, Germany

Posted 12 July 2018 - 09:38 AM

View PostBomb Bloke, on 12 July 2018 - 02:17 AM, said:

View PostBrunoZockt, on 12 July 2018 - 01:05 AM, said:

I hope you can show me what I did wrong and give a short explanation.

You're not matching the literal string "minecraft:", you're matching any of the characters contained within it:

"([^"..sep.."]+)"

Yami's gsub is indeed much simpler.

https://www.lua.org/pil/20.2.html

Also, you're making two separate statements here. One defines "t" as a local, one defines "i" as a global:

local t={} ; i=1

If you wanted to make them both local within the space of a single line, you'd do:

local t, i = {}, 1

http://lua-users.org...ignmentTutorial
Thanks a lot for the explanation. Since my function Splitter is actually supposed to match all the letters contained in the seperator, how would I change that function? Just replace string.gmatch with KingofGamesYami's solution or also remove the loop around it?
I actually knew how declaration of variables works but thanks for pointing out the mistake anyways, it's old code and I would have missed it.

View PostKingofGamesYami, on 12 July 2018 - 01:22 AM, said:

I think string.gsub( str, "minecraft:", "" ) would work much better in this case.
Thank you, will try

#5 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 6,971 posts
  • LocationTasmania (AU)

Posted 12 July 2018 - 12:40 PM

View PostBrunoZockt, on 12 July 2018 - 09:38 AM, said:

how would I change that function? Just replace string.gmatch with KingofGamesYami's solution or also remove the loop around it?

If you changed your pattern to just "minecraft:" (as opposed to "([^minecraft:]+)"), then it'd probably do what you wanted without further changes. If you switched to using gsub as well, then you could also ditch the loop and make your code simpler.

http://lua-users.org...LibraryTutorial

#6 BrunoZockt

  • Members
  • 28 posts
  • LocationHamburg, Germany

Posted 12 July 2018 - 04:21 PM

View PostBomb Bloke, on 12 July 2018 - 12:40 PM, said:

View PostBrunoZockt, on 12 July 2018 - 09:38 AM, said:

how would I change that function? Just replace string.gmatch with KingofGamesYami's solution or also remove the loop around it?

If you changed your pattern to just "minecraft:" (as opposed to "([^minecraft:]+)"), then it'd probably do what you wanted without further changes. If you switched to using gsub as well, then you could also ditch the loop and make your code simpler.

http://lua-users.org...LibraryTutorial

OK, thanks again. I got it to work and the Tutorial also gave me a good impression of the "string-thing".
But again I've encountered a problem. I want to place commas after every table value.
I came up with this:
string.gsub(textutils.serialize(variables.ignor), "minecraft:(%a+)", function(w) return w.."," end)
But "_" doesn't seem to be a letter, which results in a wrongfully placed comma "flowing,_water". I unsuccessfully tinkered around a bit to find a pattern that matches a normal "one-word name" like "minecraft:stone" aswell as a "two-or-more-words name" like "minecraft:flowing_water". Any idea?

#7 KingofGamesYami

  • Members
  • 2,969 posts
  • LocationUnited States of America

Posted 12 July 2018 - 09:05 PM

You can easily create a custom pattern to match all letters and _. It'd look something like this: "[%a_]"

#8 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 6,971 posts
  • LocationTasmania (AU)

Posted 13 July 2018 - 04:00 AM

It'd be way easier to do your matching within the original, unserialised table, though.

#9 BrunoZockt

  • Members
  • 28 posts
  • LocationHamburg, Germany

Posted 14 July 2018 - 05:45 PM

View PostKingofGamesYami, on 12 July 2018 - 09:05 PM, said:

You can easily create a custom pattern to match all letters and _. It'd look something like this: "[%a_]"
I'm sorry, but I tried out a lot of different patterns and they didn't work. Including yours. It's really frustrating but I can't figure it out.

View PostBomb Bloke, on 13 July 2018 - 04:00 AM, said:

It'd be way easier to do your matching within the original, unserialised table, though.
Could you give me an example how that would work?

#10 KingofGamesYami

  • Members
  • 2,969 posts
  • LocationUnited States of America

Posted 14 July 2018 - 06:39 PM

Have you tried "^\"" yet? That will match everything except a double quote.

#11 BrunoZockt

  • Members
  • 28 posts
  • LocationHamburg, Germany

Posted 14 July 2018 - 11:57 PM

View PostKingofGamesYami, on 14 July 2018 - 06:39 PM, said:

Have you tried "^\"" yet? That will match everything except a double quote.
No, I hadn't and it doesn't work anyways, but your post ultimately lead to me finding out about * which seems to mean "possibly" and is exactly what I needed.
My pattern that places the commas like I want them is
"minecraft:(%a+_*%a*)"
Thank you all!

#12 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 6,971 posts
  • LocationTasmania (AU)

Posted 15 July 2018 - 01:25 AM

View PostBrunoZockt, on 14 July 2018 - 05:45 PM, said:

View PostBomb Bloke, on 13 July 2018 - 04:00 AM, said:

It'd be way easier to do your matching within the original, unserialised table, though.
Could you give me an example how that would work?

local variables = {"some irrelevant stuff",
["ignor"] = {"minecraft:stone", "minecraft:cobblestone", "minecraft:dirt", "minecraft:lava", "minecraft:flowing_lava", "minecraft:water", "minecraft:flowing_water"}}

local shortnames = {}

for i = 1, #variables.ignor do shortnames[i] = variables.ignor[i]:gsub("minecraft:", "") end

printWrapped(shortnames, 18, 4, w-18)






1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users