replace() treats space-separated string list differently from string with spaces

Discuss macro implementations, ask for macro help (to share your creations, see User Creations, probably either Campaign Frameworks or Drop-in Resources).

Moderators: dorpond, trevor, Azhrei, giliath, jay, Mr.Ice

Post Reply
User avatar
Jack_Indaboks
Kobold
Posts: 2
Joined: Tue Sep 01, 2020 4:02 pm

replace() treats space-separated string list differently from string with spaces

Post by Jack_Indaboks »

This is my first post, so let me know if I posted it in the wrong place or otherwise violated the forum etiquette.

I am trying to write a UDF to fix grammatical errors in the output of other macros. It's a simple find and replace function that is basically just a wrapper for the replace() function. When I feed it a string (a whole sentence including spaces), it finds and replaces errors as expected. When I feed it a string list with a " " separator (the same sentence, but produced by another UDF), the grammatical errors go unchanged.
I don't know if this is a bug or if I'm just doing something wrong. I just want to be able to feed it a sentence, whatever the source, and have it find and replace substrings within that sentence.

When I pass a sentence directly to my edit() function in chat:

Code: Select all

[r: edit("I want a iron sword .")]
I get (I added the // comments here for clarity - they were not in the original output):

Code: Select all

I want a iron sword .	// string passed to edit() before replace()
{"a iron":"an iron"}	// json object {"error":"correct"}
I want an iron sword .	// string after "error" has been replaced by "correct"
Username:		// (no output)
(I think the [r:] roll option stopped outputting the result when I added broadcast() calls for troubleshooting, I'm not worried about it but include it here in case it's somehow related)

When I pass a sentence to a test() function that in turn passes it to edit() as a space-separated string list:

Code: Select all

[r: test("I want a iron sword .")]
I get:

Code: Select all

I want a iron sword .	// string passed to test() before transformation
I want a iron sword .	// string passed to test() after transformation
I want a iron sword .	// string passed to edit() before replace()
{"a iron":"an iron"}	// json object {"error":"correct"}
I want a iron sword .	// string after "error" should have been replaced by "correct"
Username:		// (no output)
My edit() function to fix grammatical errors:

Code: Select all

[h: line = arg(0)]
[broadcast(line)]
[h: tweaks = getLibProperty("tweaks")]
[broadcast(tweaks)]
[h,forEach(fix, tweaks): line = replace(line, "\\Q" + fix + "\\E", json.get(tweaks,fix))]
[broadcast(line)]
[h: macro.return = line]
Note: it uses broadcast() to output the original string, the json object of errors to find and replace, and the string after errors should be fixed.

My test() function that transforms the string with spaces into a space-separated string list and passes it to edit():

Code: Select all

[h: res = ""]
[broadcast(arg(0))]
[h,forEach(word,arg(0)," "," "): res = listAppend(res,word," ")]
[broadcast(res)]
[h: macro.return = edit(res)]
Note: it uses broadcast() to output the string immediately before and after transformation for troubleshooting purposes.

Also, passing the string list through string() first did not work, nor did passing it through replace() ahead of time to replace all whitespace with regular spaces. I don't know what the difference is under the hood between a sting with spaces vs a space-separated string list, but the two are identical to the end user so I don't even know the exact nature of what I am trying to fix here.

User avatar
aliasmask
RPTools Team
Posts: 9024
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

Re: replace() treats space-separated string list differently from string with spaces

Post by aliasmask »

When creating a list it trims the whitespace, but since your list separator is a space it keeps it in there. So if you had "This is a sentence" it's the same as "This,,,is,a,sentence". You want to remove extra whitespace before you convert with "\\s+"," ". To remove white space between punctuations "([\\w\\d]+)\\s+([',.-!?])","\1\2". Fixing quotes would be more tricky since they are paired. Not sure if this answers your question though.

LarryWoestman
Cave Troll
Posts: 28
Joined: Tue Jul 21, 2020 7:50 pm

Re: replace() treats space-separated string list differently from string with spaces

Post by LarryWoestman »

It appears to me that you are trying to match a string that contains a space ("a iron") to a list of "words" that can't possibly contain any spaces since you have separated them using a space as the separator. Under those conditions you can't match a pattern that contains a space.

User avatar
Jack_Indaboks
Kobold
Posts: 2
Joined: Tue Sep 01, 2020 4:02 pm

Re: replace() treats space-separated string list differently from string with spaces

Post by Jack_Indaboks »

@aliasmask That appears to have worked perfectly! Thanks!

Post Reply

Return to “Macros”