-
-
Notifications
You must be signed in to change notification settings - Fork 446
add a text replace expression #8587
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
novystar
wants to merge
25
commits into
SkriptLang:dev/feature
Choose a base branch
from
novystar:feature/replace_expression
base: dev/feature
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 15 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
58c9b77
add expr replace needs testing
novystar da375d8
add regex support, clean up getter, change non-regex to use StringUtils
novystar d50b03a
add regex support, clean up getter, change non-regex to use StringUtils
novystar 23425bd
Merge remote-tracking branch 'origin/master'
novystar 932c8a6
fix replacement null case returning null
novystar d2095f7
support for case sensitive config value
novystar a2c3703
add exprReplace, add test
novystar fd02ec2
fix some coding conventions
novystar 3d2c06a
case sensitivity test
novystar 782920e
change method order, change getAll to getArray
novystar c0bf02a
relocate ExprReplace to skriptlang common module,
novystar e7e5811
add new syntaxes that are more fitting for an expression,
novystar 87180be
rework syntaxes so they are more fitting for an expression,
novystar cd2a7c0
Apply suggestions from code review
novystar b6893ef
address missing overrides
novystar 74376bd
Apply suggestions from code review
novystar 75f0dca
Merge branch 'dev/feature' into feature/replace_expression
novystar 42b3e6f
Merge branch 'dev/feature' into feature/replace_expression
novystar 0c15105
Merge branch 'dev/feature' into feature/replace_expression
novystar c72da7c
Update src/main/java/org/skriptlang/skript/common/elements/expression…
novystar ddda881
Add more examples and Fix unhandled exception on improper use of grou…
novystar fc83b3d
Add more examples and Fix unhandled exception on improper use of grou…
novystar 1717e88
Merge remote-tracking branch 'origin/feature/replace_expression' into…
novystar e55dc9e
make is|are required in regex pattern
novystar 93d8d4b
double escape so word boundries are visible in examples
novystar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
149 changes: 149 additions & 0 deletions
149
src/main/java/org/skriptlang/skript/common/elements/expressions/ExprReplace.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,149 @@ | ||
| package org.skriptlang.skript.common.elements.expressions; | ||
|
|
||
| import ch.njol.skript.SkriptConfig; | ||
| import ch.njol.skript.doc.Description; | ||
| import ch.njol.skript.doc.Example; | ||
| import ch.njol.skript.doc.Name; | ||
| import ch.njol.skript.doc.Since; | ||
| import ch.njol.skript.lang.Expression; | ||
| import ch.njol.skript.lang.SkriptParser.ParseResult; | ||
| import ch.njol.skript.lang.SyntaxStringBuilder; | ||
| import ch.njol.skript.lang.util.SimpleExpression; | ||
| import ch.njol.util.Kleenean; | ||
| import ch.njol.util.StringUtils; | ||
| import org.bukkit.event.Event; | ||
| import org.jetbrains.annotations.Nullable; | ||
| import org.skriptlang.skript.registration.DefaultSyntaxInfos; | ||
| import org.skriptlang.skript.registration.SyntaxRegistry; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
| import java.util.regex.Matcher; | ||
| import java.util.regex.Pattern; | ||
|
|
||
| @Name("Text Replacement") | ||
| @Description("Performs a text replacement on a given value, returning the result. Supports regex and case sensitive replacement.") | ||
| @Example("send \"Welcome [player]\" where \"[player]\" is replaced with \"%player%\" to player") | ||
|
novystar marked this conversation as resolved.
|
||
| @Since("INSERT VERSION") | ||
| public class ExprReplace extends SimpleExpression<String> { | ||
|
|
||
| public static void register(SyntaxRegistry registry) { | ||
| registry.register( | ||
| SyntaxRegistry.EXPRESSION, | ||
| DefaultSyntaxInfos.Expression.builder(ExprReplace.class, String.class) | ||
| .addPatterns( | ||
| "%strings% where [(first:[the] first instance[s]|all instances) of] %strings% [is|are] replaced with %string% [regex:using regex|case:with case sensitivity]", | ||
|
novystar marked this conversation as resolved.
Outdated
|
||
| "%strings% where [(first:[the] first instance[s]|all instances) of] regex [pattern[s]] %strings% [is|are] replaced with %string%" | ||
| ) | ||
| .supplier(ExprReplace::new) | ||
| .build() | ||
| ); | ||
| } | ||
|
|
||
| private Expression<String> needleExpr; | ||
| private Expression<String> haystackExpr; | ||
| private Expression<String> replacementExpr; | ||
|
|
||
| private boolean isFirst; | ||
| private boolean isRegex = false; | ||
| private boolean isCaseSensitive = false; | ||
|
|
||
| @SuppressWarnings("unchecked") | ||
| @Override | ||
| public boolean init(Expression<?>[] expr, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { | ||
|
|
||
| haystackExpr = (Expression<String>) expr[0]; | ||
| needleExpr = (Expression<String>) expr[1]; | ||
| replacementExpr = (Expression<String>) expr[2]; | ||
|
|
||
| if (matchedPattern == 1 || parseResult.hasTag("regex")) { | ||
| isRegex = true; | ||
| } | ||
|
|
||
| isFirst = parseResult.hasTag("first"); | ||
|
|
||
| if (SkriptConfig.caseSensitive.value() || parseResult.hasTag("case")) { | ||
| isCaseSensitive = true; | ||
| } | ||
| return true; | ||
| } | ||
|
|
||
| @Override | ||
| protected String @Nullable [] get(Event event) { | ||
| String replacement = replacementExpr.getSingle(event); | ||
|
novystar marked this conversation as resolved.
|
||
| String[] needles = needleExpr.getArray(event); | ||
| String[] haystacks = haystackExpr.getArray(event); | ||
|
|
||
| if (replacement == null) { | ||
| return haystacks; | ||
| } | ||
|
|
||
| List<String> result = new ArrayList<>(haystacks.length); | ||
|
|
||
| if (isRegex) { | ||
| List<Pattern> patterns = new ArrayList<>(needles.length); | ||
| for (String needle : needles) { | ||
| try { // Pre compile regex for use with multiple haystacks | ||
| patterns.add(Pattern.compile(needle)); | ||
| } catch (Exception ignored) { | ||
| } | ||
| } | ||
|
|
||
| for (String haystack : haystacks) { | ||
| for (Pattern pattern : patterns) { | ||
| Matcher matcher = pattern.matcher(haystack); | ||
| if (isFirst) { | ||
| haystack = matcher.replaceFirst(replacement); | ||
| } else { | ||
| haystack = matcher.replaceAll(replacement); | ||
| } | ||
| } | ||
| result.add(haystack); | ||
| } | ||
| } else { | ||
| for (String haystack : haystacks) { | ||
| for (String needle : needles) { | ||
| if (isFirst) { | ||
| haystack = StringUtils.replaceFirst(haystack, needle, replacement, isCaseSensitive); | ||
| } else { | ||
| haystack = StringUtils.replace(haystack, needle, replacement, isCaseSensitive); | ||
| } | ||
| } | ||
| result.add(haystack); | ||
| } | ||
| } | ||
|
|
||
| return result.toArray(new String[0]); | ||
| } | ||
|
novystar marked this conversation as resolved.
|
||
|
|
||
| @Override | ||
| public boolean isSingle() { | ||
| return false; | ||
|
novystar marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| @Override | ||
| public boolean canBeSingle() { | ||
| return true; | ||
| } | ||
|
novystar marked this conversation as resolved.
novystar marked this conversation as resolved.
Outdated
|
||
|
|
||
| @Override | ||
| public Class<? extends String> getReturnType() { | ||
| return String.class; | ||
| } | ||
|
|
||
| @Override | ||
| public String toString(@Nullable Event event, boolean debug) { | ||
| SyntaxStringBuilder builder = new SyntaxStringBuilder(event, debug); | ||
|
|
||
| builder.append("replace"); | ||
| if (isFirst) | ||
| builder.append("first"); | ||
| if (isRegex) | ||
| builder.append("regex"); | ||
| builder.append(needleExpr, "in", haystackExpr, "with", replacementExpr); | ||
| if (isCaseSensitive) | ||
| builder.append("with case sensitivity"); | ||
|
|
||
| return builder.toString(); | ||
|
novystar marked this conversation as resolved.
|
||
| } | ||
|
novystar marked this conversation as resolved.
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| test "replace expression": | ||
|
|
||
| assert "hello this is a test" where "hello" is replaced with "goodbye" is "goodbye this is a test" with "replace" | ||
|
|
||
|
|
||
| assert "hello this is a test" where regex pattern "[el]" is replaced with "!" is "h!!!o this is a t!st" with "regex replace pattern 1" | ||
|
|
||
| assert "hello this is a test" where "[el]" is replaced with "!" using regex is "h!!!o this is a t!st" with "regex replace pattern 2" | ||
|
|
||
|
|
||
| set {_test::*} to "hello", "this", "is", "a", "test" | ||
|
|
||
| assert {_test::*} where "hello", "tes" are replaced with "!" is ("!", "this", "is", "a", "!t") with "replace list" | ||
|
|
||
| assert {_test::*} where regex "[el]" is replaced with "!" is "h!!!o", "this", "is", "a", "t!st" with "regex replace list" | ||
|
|
||
|
|
||
| assert "aaaaAAAAbbbbBBBB" where "a" is replaced with "!" with case sensitivity is "!!!!AAAAbbbbBBBB" with "replace case sensitivity" | ||
|
|
||
|
|
||
| assert "test hello test hello this is a test" where first instance of "hello" is replaced with "!" is "test ! test hello this is a test" with "replace first" | ||
|
|
||
| assert "test hello test hello this is a test" where all instances of "hello" are replaced with "!" is "test ! test ! this is a test" with "replace all" | ||
|
|
||
|
|
||
| assert "abc abcd" where first instance of regex "[ac]" is replaced with "!" is "!bc abcd" with "regex replace first" | ||
|
|
||
| assert "abc abcd" where first instance of regex "[ac]", "[acd]" is replaced with "!" is "!b! abcd" with "regex replace multi first" | ||
|
|
||
|
|
||
| set {_test::*} to "hello", "this", "is", "a", "test" | ||
|
|
||
| assert {_test::*} where first instance of "hel", "this" are replaced with "!" is ("!lo", "!", "is", "a", "test") with "first replace multi list" | ||
|
|
||
| assert {_test::*} where first instances of regex patterns "[he]", "l" are replaced with "!" is ("!e!lo", "t!is", "is", "a", "t!st") with "first regex replace multi list" |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.