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

Multi-Character Pattern Help

Started by Grim Reaper, 20 August 2014 - 08:59 PM
Grim Reaper #1
Posted 20 August 2014 - 10:59 PM
Hey, guys, I'm trying to find a more elegant solution for something I've been working on.

My problem is that I'm trying to replace all occurrences of a set of characters which are consecutively placed in a string (right next to one another) with a single string.gsub call.
For example, if I have the string

ababababcbcbcbcbefefef
, I want to get rid of everything that isn't an 'ab' pair. However, when I try the following:

string.gsub ("ababababcbcbcbcbefefef", "[^ab]")
, the output removes anything that is not either an 'a' or a 'b'. So, the in the cb pairs, the 'c' is removed, but the 'b' remains although I don't want it to do so.

I've tried

string.gsub ("ababababcbcbcbcbefefef", "[^(ab)]")
string.gsub ("ababababcbcbcbcbefefef", "[^a][^b]")
and some others without success.

The solution that I whipped up works, but it's rather verbose and fails the single statement requirement that I wanted. None the less, here it is:

local s = "ababababcbcbcbcbefefef"
local o = s:gsub ("ab", "##"):gsub ("[^##]", ";;"):gsub ("##", "ab")
This replaces all occurrences of 'ab' with '##', replaces all occurrences of anything that isn't a '##' pair with a ';;' pair, and finally replaces all '##' pairs with the desired 'ab' pair. I'm doing this so I can use gmatch to grab as many occurrences of 'ab' as possible in a single match while maintaining their positions in the line. If anyone has a suggestion to do this without isolating the pair and then using '%w%w+', then I'd love that even more than a solution to this problem :)/>.

Thanks for your help!
blunty666 #2
Posted 20 August 2014 - 11:22 PM
Hey Grim,

Using the pattern match "%bxy", where x and y are the pair of characters you are looking for is what you need.

e.g. string.gsub("ababababgh", "%bab", "") would return "gh".

That's unless you're trying to generalise to any reccuring pair in which case I'm not so sure. Just in case, here's the link to the manual: http://www.lua.org/pil/20.2.html. (The "%bxy" bit is the last paragraph)
KingofGamesYami #3
Posted 20 August 2014 - 11:28 PM
Hey Grim,

Using the pattern match "%bxy", where x and y are the pair of characters you are looking for is what you need.

e.g. string.gsub("ababababgh", "%bab", "") would return "gh".

That's unless you're trying to generalise to any reccuring pair in which case I'm not so sure. Just in case, here's the link to the manual: http://www.lua.org/pil/20.2.html. (The "%bxy" bit is the last paragraph)

That's not exactly how it works… It deletes everything between "x" and "y", including x and y.

Maybe:

str:gsub( "[AB]" )
?
Edited on 20 August 2014 - 09:35 PM
Grim Reaper #4
Posted 20 August 2014 - 11:40 PM
Hey Grim,

Using the pattern match "%bxy", where x and y are the pair of characters you are looking for is what you need.

e.g. string.gsub("ababababgh", "%bab", "") would return "gh".

That's unless you're trying to generalise to any reccuring pair in which case I'm not so sure. Just in case, here's the link to the manual: http://www.lua.org/pil/20.2.html. (The "%bxy" bit is the last paragraph)

That's not exactly how it works… It deletes everything between "x" and "y", including x and y.

Maybe:

str:gsub( "[AB]" )
?
Yami is right, it does delete everything in between. If my line starts with 'ab' and ends with 'cb', then everything will deleted in between.

Also, Yami, I've tried that solution before; it uses the character set 'ab' and matches any of the characters in the set, not just those ones. Thanks though!
blunty666 #5
Posted 21 August 2014 - 12:06 AM
Sorry discount that, was trying to think of some way to use that with some clever negation then realised what I was trying to do was:

str:gsub("b[^a]+", "b")
which is much simpler.
Grim Reaper #6
Posted 21 August 2014 - 12:20 AM
Sorry discount that, was trying to think of some way to use that with some clever negation then realised what I was trying to do was:

str:gsub("b[^a]+", "b")
which is much simpler.
This works almost perfectly: It doesn't leave the characters removed in their original position :P/> It's a much more elegant solution for doing what it does, though, so I'll keep trying to modify it or create something different to achieve what I'm after. :)/> Thanks!
Edited on 20 August 2014 - 10:23 PM
blunty666 #7
Posted 21 August 2014 - 12:34 AM
Even better :D/>

str:gsub("[a]?[b]?[^ab]", ";")

Scratch that, this doesn't work…
Edited on 20 August 2014 - 10:36 PM