String captures with string.gsub

Hello, I’m working on a simple algorithm to pluralize suffixes of common english words via string patterns. In the case below, I’m trying to match suffixes with any consonant + “y” and replace the “y” with “ies” (“Pony” > “Ponies”). This condition is unique because I don’t want to replace the full suffix, just the last letter.

I’m trying string captures to isolate the “y” and it works for string.match but not string.gsub. I’m wondering if anyone can shed some light as to why. I could use string.sub as a last resort but it doesn’t seem particularly elegant.

local noun = "Pony"
local consonant = "[^aeiouAEIOU]"
local suffix = consonant.."(y)$"
local replace = "ies"

local patternMatch = string.match(noun, suffix)
local substitutedString = string.gsub(noun, suffix, replace)

print(patternMatch) -- Output: "y"
print(substitutedString) -- Output: "Poies" Desired: "Ponies"

You can string.sub the thing you don’t want to change, and then make a new string with that string.sub and add the replacement string to it.
For example:

Pony - Turns into
Pon + replace
Ponies

Use string.match(), it supports regex.

string.find(someString, “^lol”), finds “lol” from “someString” providing “lol” appears at the start of the string (prefix), similarly $ does the reverse (suffix).

this is completely wrong

string.match supports string patterns
string.find doesn’t support string patterns

I’m looking for an alternative to stitching something together with string.sub if possible.

Was just double checking in the Lua documentation before you replied.

Will the script be going through a block of text? If so gmatch() might be more applicable here.

local noun = "Pony"
local ending = "ies"

local substitutedString = string.gsub(noun, "y?Y?%s*$", ending)

print(substitutedString)

try this
should work if the last letter is y
also y can be capitalized or lowercase here
there can also be spaces after the y if you need that

you should check before you even reply at all
don’t show information if you don’t know for sure if it is true

I’ve used string.sub with string.find inside of it because it returns the position of the vowel.
You can also use string.split

Why? A quick lookup and the information is correct, I knew the string library had regex capabilities I just had to quickly double check which functions.

image

Even if this worked for the word “Pony”, the point is to match the y only if a consonant precedes it.

Try this code out and see if you like it

local noun = "Pony"
local consonant = "[^aeiouAEIOU]"
local suffix = consonant.."(y)$"
local replace = "ies"

local patternMatch = string.sub(noun, 1, string.find(noun, suffix))
local finishedMatch = patternMatch..replace

print(finishedMatch)

It works btw

Okay so that would just tack on the plural suffix whether the noun had a match or not. The word “Pony” is just an example of a word that should match. Also, I already know I can use string.sub and concatenate. My question is specifically about gsub.

To reiterate: the purpose of this post is to find out why gsub doesn’t work with captures.

Because you are using the suffix, not the next patternMatch variable.
So you are replacing the suffix, not the patternMatch, aka “y”

local noun = "Pony"
local consonant = "[^aeiouAEIOU]"
local suffix = consonant.."(y)$"
local replace = "ies"

local patternMatch = string.match(noun, suffix)
local substitutedString = string.gsub(noun, patternMatch, replace)

print(patternMatch) -- Output: "y"
print(substitutedString) -- Output: "Poies" Desired: "Ponies"

image

Again, that only works for “Pony.” Try it with “Day”, “Cat”, “Dog”, “Pygmy” and it breaks down.

local str = "put your string here"
local letter = 1

local strLet = str:sub(letter,letter)

print(strLet) -- p lol

?

Sorry for the confusion.
Also, you wouldn’t put daies for days and caies for cats.
All you would need to do is check if it is nil and if it is don’t correct it.

Am I correct or is this wrong again?

local noun = "Dasy"
local consonant = "[^aeiouAEIOU]"
local suffix = consonant.."(y)$"
local replace = "ies"

local patternMatch = string.match(noun, suffix)
if patternMatch then
	local substitutedString = string.gsub(noun, patternMatch, replace)

	print(substitutedString) -- Output: "Poies" Desired: "Ponies"	
end

I forgot to add you can also check if the y is at the beginning or end using string.sub, and if its both at beginning and end just switch the end y to ies.

Yes but as I’ve stated several times I’m looking for a way to do this without string.sub.

There isn’t another way to do this as string.gsub doesn’t have any way to make it so you can sub 4-6 of the string. There also isn’t an alternative to string.sub too, unless you want to somehow split the string up to letters and find the ‘y’ vowel there, but that would probably be slow and take some time to make.

Now maybe you can somehow get string.gsub to sub the string without removing/replacing any characters, but again string.sub is way better.

I hope this clears things up, again sorry for the confusion. :slight_smile: