It is currently April 25th, 2024, 3:30 pm

string.match vs string.gmatch

Discuss the use of Lua in Script measures.
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

string.match vs string.gmatch

Post by jsmorley »

If you have been using string.match to parse things like an RSS feed into tables, you might consider some advantages to using string.gmatch instead.

The biggest difference is that string.match does a single match of "pattern" in "string" and you either have to repeat the variable definition and pattern xx times to get xx items parsed, or use an initial string.gsub in order to get a "count" of the items and do the string.match in a loop adding the length of the previous search as a starting index to the next. A bit ponderous either way.

With string.gmatch, the search for "pattern" in "string" is automatically done using an "iterator" that will handle much of the extra work involved with string.match.

Example:

Code: Select all

	s = '<item><title>First</title><pubdate>Monday</pubdate></item><item><title>Second</title><pubdate>Tuesday</pubdate></item><item><title>Third</title><pubdate>Wednesday</pubdate></item><title>Forth</title><pubdate>Thursday</pubdate></item>'
	count = 3
	
	-- Using string.match
	titlesm = {}
	pubdatesm = {}
	
	titlesm[1], pubdatesm[1], titlesm[2], pubdatesm[2], titlesm[3], pubdatesm[3] = string.match(s,  '<item><title>(.-)</title><pubdate>(.-)</pubdate></item><item><title>(.-)</title><pubdate>(.-)</pubdate></item><item><title>(.-)</title><pubdate>(.-)</pubdate></item>')
	
	for i = 1, count do
		print('match: '..i..' of '..count, titlesm[i], pubdatesm[i])
	end
	
	-- Using string.gmatch
	titlesg = {}
	pubdatesg = {}
	
	for sg1, sg2 in string.gmatch(s, '<item><title>(.-)</title><pubdate>(.-)</pubdate></item>') do
		table.insert(titlesg, sg1)
		table.insert(pubdatesg, sg2)
	end
	
	for i = 1, count do
		print('gmatch: '..i..' of '..count, titlesg[i], pubdatesg[i])
	end
Doesn't look like a terribly big difference with a small example of a simple parse on a few items, but when you expand this to an entire RSS feed with lots of items it can really simplify things.

http://lua-users.org/wiki/StringLibraryTutorial
User avatar
smurfier
Moderator
Posts: 1931
Joined: January 29th, 2010, 1:43 am
Location: Willmar, MN

Re: string.match vs string.gmatch

Post by smurfier »

If you want to do something simple, string.gsub can also be used to iterate over a string.

Code: Select all

function Keys(a,b) -- Converts Key="Value" sets to a table
	local tbl=b or {}
	string.gsub(a,'(%a+)=(%b"")',function (c,d) tbl[string.lower(c)]=string.match(d,'"(.+)"') end)
	return tbl
end -- function Keys
GitHub | DeviantArt | Tumblr
This is the song that never ends. It just goes on and on my friends. Some people started singing it not knowing what it was, and they'll continue singing it forever just because . . .