This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
KingofGamesYami's profile picture

Pattern help

Started by KingofGamesYami, 11 November 2014 - 04:10 PM
KingofGamesYami #1
Posted 11 November 2014 - 05:10 PM
I'm trying to make a lightweight format for crafting recipes. However, I've run into some trouble with the patterns, and I would appreciate advice here.

full code

--[[
example format (furnace):
m@minecraft;s@stone;n@none
m:s&m:s&m:s
m:s&n:n&m:s
m:s&m:s&m:s
]]--

local function parse( str )
	local tLines = {}
	for line in str:gmatch( "[^\r\n]+" ) do
		tLines[ #tLines + 1 ] = line
	end
	print( 'parsed lines' )
	print( #tLines )
	print( 'starting tShortcuts' )
	local tShortcuts = {}
	if tLines[ 1 ]:find( "@" ) then
		print( "found shortcuts" )
		--encoding is present
		for s, o in tLines[ 1 ]:gmatch( "([^@]+)@(^;+);?" ) do
			tShortcuts[ s ] = o
		end
		table.remove( tLines, 1 )
	else
		print( 'no shortcuts' )
	end
	print( #tLines )
	print( #tShortcuts )
	local tInv = {}
	local row = 0
	print( 'compiling tInv' )
	for _, str in ipairs( tLines ) do
		local l = 1
		print( str )
		for mod, item in str:gmatch( "([^:]+):(/>[^:\r\n]+)&?" ) do
			print('')
			tInv[ (row * 4) + l ] = ( tShortcuts[ mod ] or mod ) .. ":" .. ( tShortcuts[ item ] or item )
			l = l + 1
		end
		row = row + 1
	end
	return tInv
end


example format

m@minecraft;s@stone;n@none
m:s&m:s&m:s
m:s&n&m:s
m:s&m:s&m:s

expected result vs result

{
  [1] = "minecraft:stone",
  [2] = "minecraft:stone",
  [3] = "minecraft:stone",

  [5] = "minecraft:stone",
  [6] = "null:null",
  [7] = "minecraft:stone",

  [9] = "minecraft:stone",
  [10] = "minecraft:stone",
  [11] = "minecraft:stone",
}
vs

{
  [1] = "m:s&m",
  [2] = "s&m:s",
  [5] = "m:s&n&m",
  [10] = "s&m:s",
  [9] = "m:s&m",
}

I will continue to resolve this myself, however help is appreciated.

PS: I'm a bit annoyed by this, but the forum editor is inserting html end tags ('/>') in my code at random. Please ignore them, this code does not give me errors; it just doesn't work.
Edited on 11 November 2014 - 04:57 PM
Lyqyd #2
Posted 11 November 2014 - 05:41 PM
^@ means "^@", [^@] means characters other than @.
KingofGamesYami #3
Posted 11 November 2014 - 05:50 PM
^@ means "^@", [^@] means characters other than @.

That fixed some of the problems, thanks. Still not working correctly, will update OP with details.
KingofGamesYami #4
Posted 11 November 2014 - 07:11 PM
Update: Fixed more bugs, but still not working correctly
updated code

local function parse( str )
	local tLines = {}
	for line in str:gmatch( "[^\r\n]+" ) do
		tLines[ #tLines + 1 ] = line
	end
	print( 'parsed lines' )
	print( #tLines )
	print( 'starting tShortcuts' )
	local tShortcuts = {}
	if tLines[ 1 ]:find( "@" ) then
		print( "found shortcuts" )
		--encoding is present
		for s, o in tLines[ 1 ]:gmatch( "([^@]+)@([^;]+);?" ) do
			tShortcuts[ s ] = o
			print( s .. " = " .. o )
		end
		table.remove( tLines, 1 )
	else
		print( 'no shortcuts' )
	end
	local tInv = {}
	local row = 0
	print( 'compiling tInv' )
	for _, str in ipairs( tLines ) do
		local l = 1
		for mod, item in str:gmatch( "([^:]+):(/>[^:\r\n]+)&" ) do
			tInv[ (row * 4) + l ] = ( tShortcuts[ mod ] or mod ) .. ":" .. ( tShortcuts[ item ] or item )
			l = l + 1
		end
		row = row + 1
	end
	return tInv
end

What I'm trying to get out of it is still in the OP, here'w what I'm currently getting


{
  [1]="minecraft:stone",
  [2]="minecraft:stone",
  [5]="minecraft:stone",
  [6]="none:none",
  [9]="minecraft:stone",
  [10]="minecraft:stone",
}
KingofGamesYami #5
Posted 11 November 2014 - 07:19 PM
Alright, one last thing to refine…

"([^:]+):([^:\r\n]+)&"
Works, but I have to change the pattern:

[[m@minecraft;s@stone;n@none
m:s&m:s&m:s&
m:s&n:n&m:s&
m:s&m:s&m:s&]]
Lyqyd #6
Posted 11 November 2014 - 08:30 PM
Protip: the /> artifact is related to emoticons, disabling emoticons in the post prevents its appearance.

Might try:


"([^:]+):([^&]+)&

If that doesn't work, try gmatching the individual fragments against the string and see what turns up.
KingofGamesYami #7
Posted 11 November 2014 - 08:40 PM
Protip: the /> artifact is related to emoticons, disabling emoticons in the post prevents its appearance.

How? I'm in plaintext editor.
Might try:


"([^:]+):(/>/>[^&]+)&

If that doesn't work, try gmatching the individual fragments against the string and see what turns up.

I'll see how that worked out, the problem was it wouldn't recognize the last part of the line because it was not followed by a &. I attempted using &?, but that made it recognize things incorrectly.

Edit Not related to the current code, but how would I go about finding the number of times a word is in the string, eg "minecraft"?
Edited on 11 November 2014 - 07:47 PM
Lyqyd #8
Posted 11 November 2014 - 10:18 PM
Use the full editor, it's a check box on the right.

You may just want to use something like this:


"(%w+):(%w+)"

As for the number of times, gmatch with the word as the pattern and a counter variable should work.
KingofGamesYami #9
Posted 11 November 2014 - 11:55 PM
Use the full editor, it's a check box on the right.

You may just want to use something like this:


"(%w+):(/>%w+)"

As for the number of times, gmatch with the word as the pattern and a counter variable should work.

That worked.

I thought I'd probably have to resort to gmatch. Oh well…