diff --git a/README.md b/README.md index cdc90ed..b3d2a29 100644 --- a/README.md +++ b/README.md @@ -46,10 +46,10 @@ This is a maven plugin that provides various regular expression based goals to M | Goal | Description | | -------------------- | ----------- | -| `replace-file` | Apply a regular expression pattern against the contents of a file, replacing matches with the specified text. The existing file is changed. | -| `replace-properties` | Apply a regular expression pattern against a set of property values, replacing matches with the specified text, and storing in new properties. | -| `replace-property` | Apply a regular expression pattern against a property value, replacing matches with the specified text, and storing in a new property. | -| `replace-text` | Apply a regular expression pattern against text, replacing matches with the specified text, and storing in a new property. | +| `replace-file` | Apply a regular expression pattern against the contents of a file, replacing matches with the regex-compliant replacement text. The existing file is changed. | +| `replace-properties` | Apply a regular expression pattern against a set of property values, replacing matches with the regex-compliant replacement text, and storing in new properties. | +| `replace-property` | Apply a regular expression pattern against a property value, replacing matches with the regex-compliant replacement text, and storing in a new property. | +| `replace-text` | Apply a regular expression pattern against text, replacing matches with the regex-compliant replacement text, and storing in a new property. | | `match-file` | Evaluate a regular expression pattern against the contents of a file, storing the result in a boolean property. | | `match-filename` | Evaluate a regular expression pattern against the name of a file, storing the result in a boolean property. | | `match-properties` | Evaluate a regular expression pattern against a set of property values, storing the result in boolean properties. | @@ -182,3 +182,15 @@ This is a maven plugin that provides various regular expression based goals to M | `sourceDirectory` | `File` | | ${basedir} | Move all files from this directory. | | `targetDirectory` | `File` | | ${basedir} | Move all files to this directory. | | `overwrite` | `boolean` | | `true` | | + +## Model + +### Object Type: `Regex` + +| Element | Data Type | Required | Default | Description | +| ----------------- |:---------:|:--------:| ------- | ----------- | +| `pattern` | `String` | Yes | | A regular expression pattern. | +| `replacement` | `String` | | `` | A regular expression replacement string. | +| `previousPattern` | `String` | | | A regular expression pattern to look back against, removing everything down to and including the pattern. | + +The `previousPattern` allows for you to match some text and remove everything before the match, up to the `prevoiusPattern. This is useful when matching a method and removing it and all its annotations. diff --git a/src/main/java/com/inteligr8/maven/model/Regex.java b/src/main/java/com/inteligr8/maven/model/Regex.java index f9cb442..ed38d81 100644 --- a/src/main/java/com/inteligr8/maven/model/Regex.java +++ b/src/main/java/com/inteligr8/maven/model/Regex.java @@ -18,6 +18,7 @@ public class Regex implements Normalizable { private String pattern; private String replacement; + private String previousPattern; public String getPattern() { return this.pattern; @@ -27,6 +28,10 @@ public class Regex implements Normalizable { return this.replacement; } + public String getPreviousPattern() { + return previousPattern; + } + public Regex setPattern(String pattern) { this.pattern = pattern; return this; @@ -37,6 +42,11 @@ public class Regex implements Normalizable { return this; } + public Regex setPreviousPattern(String previousPattern) { + this.previousPattern = previousPattern; + return this; + } + @Override public void normalize() { if (this.replacement == null) diff --git a/src/main/java/com/inteligr8/maven/regex/AbstractReplaceMojo.java b/src/main/java/com/inteligr8/maven/regex/AbstractReplaceMojo.java index 946dd6f..8e95148 100644 --- a/src/main/java/com/inteligr8/maven/regex/AbstractReplaceMojo.java +++ b/src/main/java/com/inteligr8/maven/regex/AbstractReplaceMojo.java @@ -30,8 +30,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.ImmutableTriple; +import org.apache.commons.lang3.tuple.Triple; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Parameter; @@ -44,7 +45,7 @@ public abstract class AbstractReplaceMojo extends AbstractRegexMojo { protected List regexes; // Pattern does not implement hashCode, so not using a Map - private List> compiledRegexes; + private List> compiledRegexes; @Override protected void executeOnText(Properties props, String text, String newPropertyName) { @@ -118,12 +119,20 @@ public abstract class AbstractReplaceMojo extends AbstractRegexMojo { if (this.getLog().isDebugEnabled()) this.getLog().debug("replace first: " + text.length()); - for (Pair regex : this.compiledRegexes) { + for (Triple regex : this.compiledRegexes) { this.getLog().debug("Applying regex pattern: " + regex.getLeft()); this.getLog().debug("Operating on value: " + text); Matcher matcher = regex.getLeft().matcher(text); - text = matcher.replaceFirst(regex.getRight()); + if (regex.getRight() == null) { + text = matcher.replaceFirst(regex.getMiddle()); + } else if (matcher.find()) { + Integer previousMatchStart = this.findLastMatchIndex(regex.getRight(), text.substring(0, matcher.start())); + text = text.substring(0, previousMatchStart) + text.substring(matcher.start()); + + matcher = regex.getLeft().matcher(text); + text = matcher.replaceFirst(regex.getMiddle()); + } } return text; @@ -199,16 +208,33 @@ public abstract class AbstractReplaceMojo extends AbstractRegexMojo { if (this.getLog().isDebugEnabled()) this.getLog().debug("replace all: " + text.length()); - for (Pair regex : this.compiledRegexes) { + for (Triple regex : this.compiledRegexes) { this.getLog().debug("Applying regex pattern: " + regex.getLeft()); this.getLog().debug("Operating on value: " + text); Matcher matcher = regex.getLeft().matcher(text); - text = matcher.replaceAll(regex.getRight()); + if (regex.getRight() == null) { + text = matcher.replaceAll(regex.getMiddle()); + } else while (matcher.find()) { + Integer previousMatchStart = this.findLastMatchIndex(regex.getRight(), text.substring(0, matcher.start())); + text = text.substring(0, previousMatchStart) + text.substring(matcher.start()); + + matcher = regex.getLeft().matcher(text); + text = matcher.replaceFirst(regex.getMiddle()); + } } return text; } + + private Integer findLastMatchIndex(Pattern pattern, String text) { + Matcher matcher = pattern.matcher(text); + + Integer index = null; + while (matcher.find()) + index = matcher.start(); + return index; + } @Override protected void validateParamsPreNormalization() throws MojoFailureException { @@ -245,7 +271,9 @@ public abstract class AbstractReplaceMojo extends AbstractRegexMojo { this.getLog().debug("Compiling regex pattern: " + regex.getPattern()); try { Pattern pattern = Pattern.compile(regex.getPattern()); - this.compiledRegexes.add(new ImmutablePair(pattern, regex.getReplacement())); + String previousPatternStr = StringUtils.trimToNull(regex.getPreviousPattern()); + Pattern previousPattern = previousPatternStr == null ? null : Pattern.compile(previousPatternStr); + this.compiledRegexes.add(new ImmutableTriple<>(pattern, regex.getReplacement(), previousPattern)); } catch (PatternSyntaxException pse) { throw new MojoFailureException("'" + regex.getPattern() + "' is not a valid regular expression: " + pse.getMessage()); }