Open DocNessuno opened 4 years ago
Hard to judge whether this is a bug or not.
Current implementation of replaceAll
allows usage of Lua patterns for word
parameter.
So if you match the word with Lua expression special chars like *
it will act according to that special char logic. It really doesn't matter that this comes from string matched by trigger.
It would be possible to code escaping of those characters in replaceAll
, but in that case we lose control - we just force users to use plain strings and not leverage Lua patterns if needed.
For details how to escape string for find
or gsub
you can go to https://stackoverflow.com/questions/9790688/escaping-strings-for-gsub
And as for the issue itself I see two possible outcomes:
Let's go with (1), better functionality in the end there. I also thought we had a function to escape text for Lua patterns, but I can't find it, hmm.
Yep, you can always escape, but cannot unescape :D
Current implementation of replaceAll allows usage of Lua patterns for word parameter. So if you match the word with Lua expression special chars like * it will act according to that special char logic. It really doesn't matter that this comes from string matched by trigger.
Understandable, but the behavior seems even different from LUA (particularly, I struggle to follow the logic of example number 3).
Let's go with (1), better functionality in the end there. I also thought we had a function to escape text for Lua patterns, but I can't find it, hmm.
I would suggest at least having an escape function available so something like replaceAll(luaEscape(matches[1]),"WORKS")
could be used, while I understand your concern, I believe that the cases were users want an exact match for replace
or replaceAll
severely outnumber the ones where they are interested in using LUA special characters.
https://gitspartv.github.io/lua-patterns/?pattern=%7C*%7C
So first pipe can show up 0 or more times. Second pipe must always be present.
Possible matches for the pattern:
|
-> |*
this allows 0 matches
||
-> |*
1 match
|||
etc.
Therefore in example 3 - both pipes are matched and replaced.
I have no idea whether this makes clear explanation.
https://gitspartv.github.io/lua-patterns/?pattern=%7C*%7C
So first pipe can show up 0 or more times. Second pipe must always be present.
Possible matches for the pattern:
|
->|*
this allows 0 matches||
->|*
1 match|||
etc.Therefore in example 3 - both pipes are matched and replaced.
I have no idea whether this makes clear explanation.
I see your point, but consider that the pipes are not sent to the replaceAll command at all (to my understanding at least)
Example 3 should be equivalent to replaceAll("*","WORKS")
on You say '|*|'
What do you mean they're not sent? They are part of the pattern.
Example 3 is not, nor should be equivalent to replaceAll("*","WORKS")
Single *
is *
literally, while |*
is match 0+ |
Summary:
replaceAll misbehaves (fails to replace the string without any error or replaces the string in odd/unexpected ways) when the string involves pipes and asterisks
Steps to reproduce:
Perl trigger:
\|(.+)\|
Trigger body:replaceAll(matches[1],"WORKS")
Test output:
You say '|Test|'
You say '|:|'
You say '|*|'
You say '|Test:|'
You say '|Test*|'
You say '|:*|'
You say '|Test:*|'
Expected behavior:
You say 'WORKS'
Actual behavior:
You say 'WORKS'
You say 'WORKS'
You say 'WORKS*WORKS'
You say 'WORKS'
You say '|Test*|'
You say '|:*|'
You say '|Test:*|'
Extra information: Mudlet 4.10.0 - Windows 10 using
selectString()
andreplace()
does not incur in the same issues usingreplaceAll(matches[2],"WORKS")
sorta functions as expected but not really (for example replaces '|Test:|'` with '|WORKS|'- note the spurious
the issue present itself even when the pipes are not the delimiting elements, such as in the following Perl regex
(?:<!ENTITY Gruppo "tank:.+?|mob:.+?)?|(\w+?)when the output is
... tank:|mob:*|Ashur ...`